diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 74b1e9240d43421dc8d742c2ec2357216b069b48..739fd38a9a68dcfcdff8bd77caccd3c18edc7bcd 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -70,3 +70,6 @@ f6d557ee34b6bbdb1dc32f29e34b4a4a8ad35e81 # [libc++] Replace uses of _VSTD:: by std:: (#74331) 77a00c0d546cd4aa8311b5b9031ae9ea8cdb050c + +# [libc++] Format the code base (#74334) +9783f28cbb155e4a8d49c12e1c60ce14dcfaf0c7 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..6b281f33f737db9ae661e80cfa66c5c778b11cb6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,142 @@ +libcxx/src/**/*.cpp merge=libcxx-reformat +libcxx/include/**/*.h merge=libcxx-reformat + +# Explicitly handle files with no extension +libcxx/include/__availability merge=libcxx-reformat +libcxx/include/__bit_reference merge=libcxx-reformat +libcxx/include/__config merge=libcxx-reformat +libcxx/include/__hash_table merge=libcxx-reformat +libcxx/include/__locale merge=libcxx-reformat +libcxx/include/__node_handle merge=libcxx-reformat +libcxx/include/__split_buffer merge=libcxx-reformat +libcxx/include/__std_clang_module merge=libcxx-reformat +libcxx/include/__threading_support merge=libcxx-reformat +libcxx/include/__tree merge=libcxx-reformat +libcxx/include/__verbose_abort merge=libcxx-reformat +libcxx/include/algorithm merge=libcxx-reformat +libcxx/include/any merge=libcxx-reformat +libcxx/include/array merge=libcxx-reformat +libcxx/include/atomic merge=libcxx-reformat +libcxx/include/barrier merge=libcxx-reformat +libcxx/include/bit merge=libcxx-reformat +libcxx/include/bitset merge=libcxx-reformat +libcxx/include/cassert merge=libcxx-reformat +libcxx/include/ccomplex merge=libcxx-reformat +libcxx/include/cctype merge=libcxx-reformat +libcxx/include/cerrno merge=libcxx-reformat +libcxx/include/cfenv merge=libcxx-reformat +libcxx/include/cfloat merge=libcxx-reformat +libcxx/include/charconv merge=libcxx-reformat +libcxx/include/chrono merge=libcxx-reformat +libcxx/include/cinttypes merge=libcxx-reformat +libcxx/include/ciso646 merge=libcxx-reformat +libcxx/include/climits merge=libcxx-reformat +libcxx/include/clocale merge=libcxx-reformat +libcxx/include/cmath merge=libcxx-reformat +libcxx/include/codecvt merge=libcxx-reformat +libcxx/include/compare merge=libcxx-reformat +libcxx/include/complex merge=libcxx-reformat +libcxx/include/concepts merge=libcxx-reformat +libcxx/include/condition_variable merge=libcxx-reformat +libcxx/include/coroutine merge=libcxx-reformat +libcxx/include/csetjmp merge=libcxx-reformat +libcxx/include/csignal merge=libcxx-reformat +libcxx/include/cstdarg merge=libcxx-reformat +libcxx/include/cstdbool merge=libcxx-reformat +libcxx/include/cstddef merge=libcxx-reformat +libcxx/include/cstdint merge=libcxx-reformat +libcxx/include/cstdio merge=libcxx-reformat +libcxx/include/cstdlib merge=libcxx-reformat +libcxx/include/cstring merge=libcxx-reformat +libcxx/include/ctgmath merge=libcxx-reformat +libcxx/include/ctime merge=libcxx-reformat +libcxx/include/cuchar merge=libcxx-reformat +libcxx/include/cwchar merge=libcxx-reformat +libcxx/include/cwctype merge=libcxx-reformat +libcxx/include/deque merge=libcxx-reformat +libcxx/include/exception merge=libcxx-reformat +libcxx/include/execution merge=libcxx-reformat +libcxx/include/expected merge=libcxx-reformat +libcxx/include/experimental/__config merge=libcxx-reformat +libcxx/include/experimental/__memory merge=libcxx-reformat +libcxx/include/experimental/deque merge=libcxx-reformat +libcxx/include/experimental/forward_list merge=libcxx-reformat +libcxx/include/experimental/iterator merge=libcxx-reformat +libcxx/include/experimental/list merge=libcxx-reformat +libcxx/include/experimental/map merge=libcxx-reformat +libcxx/include/experimental/memory merge=libcxx-reformat +libcxx/include/experimental/memory_resource merge=libcxx-reformat +libcxx/include/experimental/propagate_const merge=libcxx-reformat +libcxx/include/experimental/regex merge=libcxx-reformat +libcxx/include/experimental/set merge=libcxx-reformat +libcxx/include/experimental/simd merge=libcxx-reformat +libcxx/include/experimental/string merge=libcxx-reformat +libcxx/include/experimental/type_traits merge=libcxx-reformat +libcxx/include/experimental/unordered_map merge=libcxx-reformat +libcxx/include/experimental/unordered_set merge=libcxx-reformat +libcxx/include/experimental/utility merge=libcxx-reformat +libcxx/include/experimental/vector merge=libcxx-reformat +libcxx/include/ext/__hash merge=libcxx-reformat +libcxx/include/ext/hash_map merge=libcxx-reformat +libcxx/include/ext/hash_set merge=libcxx-reformat +libcxx/include/filesystem merge=libcxx-reformat +libcxx/include/format merge=libcxx-reformat +libcxx/include/forward_list merge=libcxx-reformat +libcxx/include/fstream merge=libcxx-reformat +libcxx/include/functional merge=libcxx-reformat +libcxx/include/future merge=libcxx-reformat +libcxx/include/initializer_list merge=libcxx-reformat +libcxx/include/iomanip merge=libcxx-reformat +libcxx/include/ios merge=libcxx-reformat +libcxx/include/iosfwd merge=libcxx-reformat +libcxx/include/iostream merge=libcxx-reformat +libcxx/include/istream merge=libcxx-reformat +libcxx/include/iterator merge=libcxx-reformat +libcxx/include/latch merge=libcxx-reformat +libcxx/include/limits merge=libcxx-reformat +libcxx/include/list merge=libcxx-reformat +libcxx/include/locale merge=libcxx-reformat +libcxx/include/map merge=libcxx-reformat +libcxx/include/mdspan merge=libcxx-reformat +libcxx/include/memory merge=libcxx-reformat +libcxx/include/memory_resource merge=libcxx-reformat +libcxx/include/mutex merge=libcxx-reformat +libcxx/include/new merge=libcxx-reformat +libcxx/include/numbers merge=libcxx-reformat +libcxx/include/numeric merge=libcxx-reformat +libcxx/include/optional merge=libcxx-reformat +libcxx/include/ostream merge=libcxx-reformat +libcxx/include/print merge=libcxx-reformat +libcxx/include/queue merge=libcxx-reformat +libcxx/include/random merge=libcxx-reformat +libcxx/include/ranges merge=libcxx-reformat +libcxx/include/ratio merge=libcxx-reformat +libcxx/include/regex merge=libcxx-reformat +libcxx/include/scoped_allocator merge=libcxx-reformat +libcxx/include/semaphore merge=libcxx-reformat +libcxx/include/set merge=libcxx-reformat +libcxx/include/shared_mutex merge=libcxx-reformat +libcxx/include/source_location merge=libcxx-reformat +libcxx/include/span merge=libcxx-reformat +libcxx/include/sstream merge=libcxx-reformat +libcxx/include/stack merge=libcxx-reformat +libcxx/include/stdexcept merge=libcxx-reformat +libcxx/include/stop_token merge=libcxx-reformat +libcxx/include/streambuf merge=libcxx-reformat +libcxx/include/string merge=libcxx-reformat +libcxx/include/string_view merge=libcxx-reformat +libcxx/include/strstream merge=libcxx-reformat +libcxx/include/syncstream merge=libcxx-reformat +libcxx/include/system_error merge=libcxx-reformat +libcxx/include/thread merge=libcxx-reformat +libcxx/include/tuple merge=libcxx-reformat +libcxx/include/type_traits merge=libcxx-reformat +libcxx/include/typeindex merge=libcxx-reformat +libcxx/include/typeinfo merge=libcxx-reformat +libcxx/include/unordered_map merge=libcxx-reformat +libcxx/include/unordered_set merge=libcxx-reformat +libcxx/include/utility merge=libcxx-reformat +libcxx/include/valarray merge=libcxx-reformat +libcxx/include/variant merge=libcxx-reformat +libcxx/include/vector merge=libcxx-reformat +libcxx/include/version merge=libcxx-reformat diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8afd2b9ce4a1c14e02ae36f66af2cd2e59c9d623..988302e6a57ad3f4765752494e8611f399aa14ba 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -33,44 +33,67 @@ /lldb/ @JDevlieghere -# Linalg in MLIR. +# MLIR Interfaces. +/mlir/include/mlir/Interfaces/TilingInterface.* @MaheshRavishankar @nicolasvasilache +/mlir/lib/Interfaces/TilingInterface.* @MaheshRavishankar @nicolasvasilache +/mlir/include/mlir/Interfaces/ValueBoundsOpInterface.* @matthias-springer +/mlir/lib/Interfaces/ValueBoundsOpInterface.* @matthias-springer +/mlir/**/ValueBoundsOpInterfaceImpl.* @matthias-springer +/mlir/include/mlir/Interfaces/RuntimeVerifiableOpInterface.* @matthias-springer +/mlir/lib/Interfaces/RuntimeVerifiableOpInterface.* @matthias-springer +/mlir/**/RuntimeVerifiableOpInterfaceImpl.* @matthias-springer +/mlir/include/mlir/Interfaces/SubsetOpInterface.* @matthias-springer +/mlir/lib/Interfaces/SubsetOpInterface.* @matthias-springer +/mlir/**/SubsetOpInterfaceImpl.* @matthias-springer +/mlir/include/mlir/Interfaces/DestinationStyleOpInterface.* @matthias-springer +/mlir/lib/Interfaces/DestinationStyleOpInterface.* @matthias-springer + +# Bufferization Dialect in MLIR. +/mlir/include/mlir/Dialect/Bufferization @matthias-springer +/mlir/lib/Dialect/Bufferization @matthias-springer +/mlir/**/BufferizableOpInterfaceImpl.* @matthias-springer +/mlir/Dialect/*/Transforms/Bufferize.cpp @matthias-springer + +# Linalg Dialect in MLIR. /mlir/include/mlir/Dialect/Linalg @dcaballe @nicolasvasilache /mlir/lib/Dialect/Linalg @dcaballe @nicolasvasilache +/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp @MaheshRavishankar @nicolasvasilache +/mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp @MaheshRavishankar @nicolasvasilache +/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp @MaheshRavishankar @nicolasvasilache +/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @hanhanW @nicolasvasilache +/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp @hanhanW @nicolasvasilache +/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @hanhanW @nicolasvasilache -# Vector in MLIR. +# MemRef Dialect in MLIR. +/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp @MaheshRavishankar @nicolasvasilache + +# Vector Dialect in MLIR. /mlir/**/*AMX* @dcaballe /mlir/**/*Neon* @banach-space @dcaballe @nicolasvasilache /mlir/**/*SME* @banach-space @dcaballe @nicolasvasilache /mlir/**/*SVE* @banach-space @dcaballe @nicolasvasilache /mlir/**/*VectorInterfaces* @dcaballe @nicolasvasilache -/mlir/**/*VectorToSCF* @banach-space @dcaballe @nicolasvasilache +/mlir/**/*VectorToSCF* @banach-space @dcaballe @nicolasvasilache @matthias-springer /mlir/**/*VectorToLLVM* @banach-space @dcaballe @nicolasvasilache /mlir/**/*X86Vector* @dcaballe @nicolasvasilache /mlir/include/mlir/Dialect/Vector @dcaballe @nicolasvasilache /mlir/lib/Dialect/Vector @dcaballe @nicolasvasilache - -/mlir/include/mlir/Interfaces/TilingInterface.* @MaheshRavishankar @nicolasvasilache - -/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp @MaheshRavishankar @nicolasvasilache -/mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp @MaheshRavishankar @nicolasvasilache -/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp @MaheshRavishankar @nicolasvasilache -/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp @MaheshRavishankar @nicolasvasilache /mlir/lib/Dialect/Vector/Transforms/VectorEmulateNarrowType.cpp @MaheshRavishankar @nicolasvasilache -/mlir/lib/Interfaces/TilingInterface.* @MaheshRavishankar @nicolasvasilache - /mlir/**/*EmulateNarrowType* @hanhanW -/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @hanhanW @nicolasvasilache -/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp @hanhanW @nicolasvasilache -/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @hanhanW @nicolasvasilache -/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @hanhanW @nicolasvasilache -/mlir/lib/Dialect/Tensor/Transforms/FoldIntoPackAndUnpackPatterns.cpp @hanhanW @nicolasvasilache /mlir/lib/Dialect/Vector/Transforms/* @hanhanW @nicolasvasilache +# Presburger library in MLIR +/mlir/**/*Presburger* @Groverkss @Superty + +# Tensor Dialect in MLIR. +/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @hanhanW @nicolasvasilache +/mlir/lib/Dialect/Tensor/Transforms/* @hanhanW @nicolasvasilache + # Transform Dialect in MLIR. /mlir/include/mlir/Dialect/Transform/* @ftynse @nicolasvasilache /mlir/lib/Dialect/Transform/* @ftynse @nicolasvasilache -# SPIR-V in MLIR. +# SPIR-V Dialect in MLIR. /mlir/**/SPIRV/ @antiagainst @kuhar /mlir/**/SPIRVTo*/ @antiagainst @kuhar /mlir/**/*ToSPIRV/ @antiagainst @kuhar diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index 370cf830a60cf8f0a0558503422e4f14c441fdd4..25e8c8c1ef21aa7539d4f58e0d81d4901ed0e421 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -185,7 +185,7 @@ jobs: std_modules: 'OFF' # Use a larger machine for MSAN to avoid timeout and memory allocation issues. - config: 'generic-msan' - machine: libcxx-runners-32-set + machine: libcxx-runners-8-set std_modules: 'OFF' runs-on: ${{ matrix.machine }} steps: diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index 75d4f419ab1fdc1e4f1089951824afa20ca876c0..4e3eaff97a87832065710048a269100f5a922bd9 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -15,6 +15,9 @@ on: description: 'Tag to build' required: true type: string + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '0 8 1 * *' permissions: contents: read # Default everything to read-only @@ -26,7 +29,7 @@ jobs: if: github.repository == 'llvm/llvm-project' outputs: release-version: ${{ steps.validate-tag.outputs.release-version }} - release: ${{ steps.validate-tag.outputs.release }} + flags: ${{ steps.validate-tag.outputs.flags }} build-dir: ${{ steps.validate-tag.outputs.build-dir }} rc-flags: ${{ steps.validate-tag.outputs.rc-flags }} ref: ${{ steps.validate-tag.outputs.ref }} @@ -50,6 +53,11 @@ jobs: tag="${{ github.ref_name }}" trimmed=$(echo ${{ inputs.tag }} | xargs) [[ "$trimmed" != "" ]] && tag="$trimmed" + if [ "$tag" = "main" ]; then + # If tag is main, then we've been triggered by a scheduled so pass so + # use the head commit as the tag. + tag=`git rev-parse HEAD` + fi if [ -n "${{ inputs.upload }}" ]; then upload="${{ inputs.upload }}" else @@ -71,7 +79,7 @@ jobs: - name: Checkout LLVM uses: actions/checkout@v4 with: - ref: ${{ inputs.tag || github.ref_name }} + ref: ${{ needs.prepare.outputs.ref }} - name: Install Ninja uses: llvm/actions/install-ninja@main @@ -140,8 +148,7 @@ jobs: - name: Build and test release run: | ${{ needs.prepare.outputs.build-dir }}/llvm-project/llvm/utils/release/test-release.sh \ - -release ${{ needs.prepare.outputs.release }} \ - ${{ needs.prepare.outputs.rc-flags }} \ + ${{ needs.prepare.outputs.flags }} \ -triple ${{ matrix.target.triple }} \ -use-ninja \ -no-checkout \ diff --git a/.github/workflows/set-release-binary-outputs.sh b/.github/workflows/set-release-binary-outputs.sh index 8a7944e7e55fa06a4ddb5443df00021d00ae324a..9bc459a24e80194d4f5fa076e5d3a8939204f668 100644 --- a/.github/workflows/set-release-binary-outputs.sh +++ b/.github/workflows/set-release-binary-outputs.sh @@ -16,19 +16,32 @@ if [[ "$github_user" != "tstellar" && "$github_user" != "tru" ]]; then echo "ERROR: User not allowed: $github_user" exit 1 fi -pattern='^llvmorg-[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc[0-9]\+\)\?$' -echo "$tag" | grep -e $pattern -if [ $? != 0 ]; then - echo "ERROR: Tag '$tag' doesn't match pattern: $pattern" - exit 1 + +if echo $tag | grep -e '^[0-9a-f]\+$'; then + # This is a plain commit. + # TODO: Don't hardcode this. + release_version="18" + build_dir="$tag" + upload='false' + ref="$tag" + flags="-git-ref $tag -test-asserts" + +else + + pattern='^llvmorg-[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc[0-9]\+\)\?$' + echo "$tag" | grep -e $pattern + if [ $? != 0 ]; then + echo "ERROR: Tag '$tag' doesn't match pattern: $pattern" + exit 1 + fi + release_version=`echo "$tag" | sed 's/llvmorg-//g'` + release=`echo "$release_version" | sed 's/-.*//g'` + build_dir=`echo "$release_version" | sed 's,^[^-]\+,final,' | sed 's,[^-]\+-rc\(.\+\),rc\1,'` + rc_flags=`echo "$release_version" | sed 's,^[^-]\+,-final,' | sed 's,[^-]\+-rc\(.\+\),-rc \1 -test-asserts,' | sed 's,--,-,'` + flags="-release $release $rc_flags" fi -release_version=`echo "$tag" | sed 's/llvmorg-//g'` -release=`echo "$release_version" | sed 's/-.*//g'` -build_dir=`echo "$release_version" | sed 's,^[^-]\+,final,' | sed 's,[^-]\+-rc\(.\+\),rc\1,'` -rc_flags=`echo "$release_version" | sed 's,^[^-]\+,-final,' | sed 's,[^-]\+-rc\(.\+\),-rc \1 -test-asserts,' | sed 's,--,-,'` echo "release-version=$release_version" >> $GITHUB_OUTPUT -echo "release=$release" >> $GITHUB_OUTPUT echo "build-dir=$build_dir" >> $GITHUB_OUTPUT -echo "rc-flags=$rc_flags" >> $GITHUB_OUTPUT +echo "flags=$flags" >> $GITHUB_OUTPUT echo "upload=$upload" >> $GITHUB_OUTPUT echo "ref=$tag" >> $GITHUB_OUTPUT diff --git a/.mailmap b/.mailmap index d5464cf9e81529d0fc28e440c16e9ae7980755d5..6211922135257c6085dbc1e485627f4a3de1060a 100644 --- a/.mailmap +++ b/.mailmap @@ -43,6 +43,7 @@ Martin Storsjö Med Ismail Bennani Med Ismail Bennani Ramkumar Ramachandra +Ramkumar Ramachandra Saleem Abdulrasool Tommy Chiang Wang Pengcheng diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index c7672285b06c09f8f99123e34e8e35dd8793c21a..f0e7a8272ad0ee491706ce8d24cb2dfcecd89d21 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -900,8 +900,8 @@ public: /// Return true if \p SymbolName was generated internally and was not present /// in the input binary. bool isInternalSymbolName(const StringRef Name) { - return Name.startswith("SYMBOLat") || Name.startswith("DATAat") || - Name.startswith("HOLEat"); + return Name.starts_with("SYMBOLat") || Name.starts_with("DATAat") || + Name.starts_with("HOLEat"); } MCSymbol *getHotTextStartSymbol() const { diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index 1c5252142d4ebf52c205d50443ca02eb8e356ff6..f89084065aae1c45157e6ad9b78bf12af851c5f0 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -33,6 +33,7 @@ namespace llvm { namespace bolt { class DIEStreamer; +class DebugStrOffsetsWriter; class DIEBuilder { friend DIEStreamer; @@ -266,7 +267,8 @@ public: ProcessingType getCurrentProcessingState() { return getState().Type; } /// Constructs IR for Type Units. - void buildTypeUnits(const bool Init = true); + void buildTypeUnits(DebugStrOffsetsWriter *StrOffsetWriter = nullptr, + const bool Init = true); /// Constructs IR for all the CUs. void buildCompileUnits(const bool Init = true); /// Constructs IR for CUs in a vector. diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h index 9f0dd88b115fcc41ab88e1ad25e9f2a39874d3d7..31a636ba2ce6539df191d21346722d10b5b313d2 100644 --- a/bolt/include/bolt/Core/DebugData.h +++ b/bolt/include/bolt/Core/DebugData.h @@ -436,10 +436,6 @@ public: StrOffsetsStream = std::make_unique(*StrOffsetsBuffer); } - /// Initializes Buffer and Stream. - void initialize(const DWARFSection &StrOffsetsSection, - const std::optional Contr); - /// Update Str offset in .debug_str in .debug_str_offsets. void updateAddressMap(uint32_t Index, uint32_t Address); @@ -455,9 +451,13 @@ public: } private: + /// Initializes Buffer and Stream. + void initialize(DWARFUnit &Unit); + std::unique_ptr StrOffsetsBuffer; std::unique_ptr StrOffsetsStream; std::map IndexToAddressMap; + std::vector StrOffsets; std::unordered_map ProcessedBaseOffsets; bool StrOffsetSectionWasModified = false; }; diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index 7b78c9ba30a3032c554bc0784f8aafebd78294bc..3f96ea265e425f72380585aa6f8a08d2ac4deaa9 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -1086,7 +1086,7 @@ void BinaryContext::generateSymbolHashes() { auto isPadding = [](const BinaryData &BD) { StringRef Contents = BD.getSection().getContents(); StringRef SymData = Contents.substr(BD.getOffset(), BD.getSize()); - return (BD.getName().startswith("HOLEat") || + return (BD.getName().starts_with("HOLEat") || SymData.find_first_not_of(0) == StringRef::npos); }; @@ -1326,8 +1326,8 @@ void BinaryContext::postProcessSymbolTable() { bool Valid = true; for (auto &Entry : BinaryDataMap) { BinaryData *BD = Entry.second; - if ((BD->getName().startswith("SYMBOLat") || - BD->getName().startswith("DATAat")) && + if ((BD->getName().starts_with("SYMBOLat") || + BD->getName().starts_with("DATAat")) && !BD->getParent() && !BD->getSize() && !BD->isAbsolute() && BD->getSection()) { errs() << "BOLT-WARNING: zero-sized top level symbol: " << *BD << "\n"; @@ -1410,9 +1410,9 @@ void BinaryContext::fixBinaryDataHoles() { auto isNotHole = [&Section](const binary_data_iterator &Itr) { BinaryData *BD = Itr->second; bool isHole = (!BD->getParent() && !BD->getSize() && BD->isObject() && - (BD->getName().startswith("SYMBOLat0x") || - BD->getName().startswith("DATAat0x") || - BD->getName().startswith("ANONYMOUS"))); + (BD->getName().starts_with("SYMBOLat0x") || + BD->getName().starts_with("DATAat0x") || + BD->getName().starts_with("ANONYMOUS"))); return !isHole && BD->getSection() == Section && !BD->getParent(); }; @@ -1818,14 +1818,14 @@ MarkerSymType BinaryContext::getMarkerType(const SymbolRef &Symbol) const { if (*TypeOrError != SymbolRef::ST_Unknown) return MarkerSymType::NONE; - if (*NameOrError == "$x" || NameOrError->startswith("$x.")) + if (*NameOrError == "$x" || NameOrError->starts_with("$x.")) return MarkerSymType::CODE; // $x - if (isRISCV() && NameOrError->startswith("$x")) + if (isRISCV() && NameOrError->starts_with("$x")) return MarkerSymType::CODE; - if (*NameOrError == "$d" || NameOrError->startswith("$d.")) + if (*NameOrError == "$d" || NameOrError->starts_with("$d.")) return MarkerSymType::DATA; return MarkerSymType::NONE; diff --git a/bolt/lib/Core/BinaryData.cpp b/bolt/lib/Core/BinaryData.cpp index f963406c17d58cedf4000e30fcdcea4d9b4dc4d0..0068a935800429f6b9f4cf0c56cef813f0af0486 100644 --- a/bolt/lib/Core/BinaryData.cpp +++ b/bolt/lib/Core/BinaryData.cpp @@ -65,7 +65,7 @@ bool BinaryData::hasNameRegex(StringRef NameRegex) const { bool BinaryData::nameStartsWith(StringRef Prefix) const { for (const MCSymbol *Symbol : Symbols) - if (Symbol->getName().startswith(Prefix)) + if (Symbol->getName().starts_with(Prefix)) return true; return false; } diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index b809b2935ee9ebf04c0e631f96f14807febdefa2..762d3419edd340c8276df08e9f6ceb7e559b35a2 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -189,7 +189,8 @@ static unsigned int getCUNum(DWARFContext *DwarfContext, bool IsDWO) { return CUNum; } -void DIEBuilder::buildTypeUnits(const bool Init) { +void DIEBuilder::buildTypeUnits(DebugStrOffsetsWriter *StrOffsetWriter, + const bool Init) { if (Init) BuilderState.reset(new State()); @@ -229,8 +230,11 @@ void DIEBuilder::buildTypeUnits(const bool Init) { registerUnit(*DU.get(), false); } - for (DWARFUnit *DU : getState().DWARF5TUVector) + for (DWARFUnit *DU : getState().DWARF5TUVector) { constructFromUnit(*DU); + if (StrOffsetWriter) + StrOffsetWriter->finalizeSection(*DU, *this); + } } void DIEBuilder::buildCompileUnits(const bool Init) { @@ -262,13 +266,11 @@ void DIEBuilder::buildCompileUnits(const bool Init) { } void DIEBuilder::buildCompileUnits(const std::vector &CUs) { BuilderState.reset(new State()); - // Initializing to full size because there could be cross CU references with - // different abbrev offsets. LLVM happens to output CUs that have cross CU - // references with the same abbrev table. So destinations end up in the first - // set, even if they themselves don't have src cross cu ref. We could have - // cases where this is not the case. In which case this container needs to be - // big enough for all. - getState().CloneUnitCtxMap.resize(DwarfContext->getNumCompileUnits()); + // Allocating enough for current batch being processed. + // In real use cases we either processing a batch of CUs with no cross + // references, or if they do have them it is due to LTO. With clang they will + // share the same abbrev table. In either case this vector will not grow. + getState().CloneUnitCtxMap.resize(CUs.size()); getState().Type = ProcessingType::CUs; for (DWARFUnit *CU : CUs) registerUnit(*CU, false); @@ -280,7 +282,7 @@ void DIEBuilder::buildCompileUnits(const std::vector &CUs) { void DIEBuilder::buildDWOUnit(DWARFUnit &U) { BuilderState.release(); BuilderState = std::make_unique(); - buildTypeUnits(false); + buildTypeUnits(nullptr, false); getState().Type = ProcessingType::CUs; registerUnit(U, false); constructFromUnit(U); @@ -893,6 +895,10 @@ void DIEBuilder::registerUnit(DWARFUnit &DU, bool NeedSort) { }); } getState().UnitIDMap[getHash(DU)] = getState().DUList.size(); + // This handles the case where we do have cross cu references, but CUs do not + // share the same abbrev table. + if (getState().DUList.size() == getState().CloneUnitCtxMap.size()) + getState().CloneUnitCtxMap.emplace_back(); getState().DUList.push_back(&DU); } diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp index dcf3a36e35e3fcfc3b773054fba1ad05faa29167..415b0310b6bac84c2daee8a26faea78ad850ae91 100644 --- a/bolt/lib/Core/DebugData.cpp +++ b/bolt/lib/Core/DebugData.cpp @@ -851,35 +851,34 @@ std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) { return BinaryContentsStr; } -void DebugStrOffsetsWriter::initialize( - const DWARFSection &StrOffsetsSection, - const std::optional Contr) { +void DebugStrOffsetsWriter::initialize(DWARFUnit &Unit) { + if (Unit.getVersion() < 5) + return; + const DWARFSection &StrOffsetsSection = Unit.getStringOffsetSection(); + const std::optional &Contr = + Unit.getStringOffsetsTableContribution(); if (!Contr) return; - const uint8_t DwarfOffsetByteSize = Contr->getDwarfOffsetByteSize(); assert(DwarfOffsetByteSize == 4 && "Dwarf String Offsets Byte Size is not supported."); - uint32_t Index = 0; + StrOffsets.reserve(Contr->Size); for (uint64_t Offset = 0; Offset < Contr->Size; Offset += DwarfOffsetByteSize) - IndexToAddressMap[Index++] = support::endian::read32le( - StrOffsetsSection.Data.data() + Contr->Base + Offset); + StrOffsets.push_back(support::endian::read32le( + StrOffsetsSection.Data.data() + Contr->Base + Offset)); } void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) { - assert(IndexToAddressMap.count(Index) > 0 && "Index is not found."); IndexToAddressMap[Index] = Address; StrOffsetSectionWasModified = true; } void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit, DIEBuilder &DIEBldr) { - if (IndexToAddressMap.empty()) - return; - std::optional AttrVal = findAttributeInfo(Unit.getUnitDIE(), dwarf::DW_AT_str_offsets_base); - assert(AttrVal && "DW_AT_str_offsets_base not present."); + if (!AttrVal) + return; std::optional Val = AttrVal->V.getAsSectionOffset(); assert(Val && "DW_AT_str_offsets_base Value not present."); DIE &Die = *DIEBldr.getUnitDIEbyUnit(Unit); @@ -888,11 +887,14 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit, auto RetVal = ProcessedBaseOffsets.find(*Val); // Handling re-use of str-offsets section. if (RetVal == ProcessedBaseOffsets.end() || StrOffsetSectionWasModified) { + initialize(Unit); + // Update String Offsets that were modified. + for (const auto &Entry : IndexToAddressMap) + StrOffsets[Entry.first] = Entry.second; // Writing out the header for each section. - support::endian::write( - *StrOffsetsStream, - static_cast(IndexToAddressMap.size() * 4 + 4), - llvm::endianness::little); + support::endian::write(*StrOffsetsStream, + static_cast(StrOffsets.size() * 4 + 4), + llvm::endianness::little); support::endian::write(*StrOffsetsStream, static_cast(5), llvm::endianness::little); support::endian::write(*StrOffsetsStream, static_cast(0), @@ -904,8 +906,8 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit, DIEBldr.replaceValue(&Die, dwarf::DW_AT_str_offsets_base, StrListBaseAttrInfo.getForm(), DIEInteger(BaseOffset)); - for (const auto &Entry : IndexToAddressMap) - support::endian::write(*StrOffsetsStream, Entry.second, + for (const uint32_t Offset : StrOffsets) + support::endian::write(*StrOffsetsStream, Offset, llvm::endianness::little); } else { DIEBldr.replaceValue(&Die, dwarf::DW_AT_str_offsets_base, @@ -915,6 +917,7 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit, StrOffsetSectionWasModified = false; IndexToAddressMap.clear(); + StrOffsets.clear(); } void DebugStrWriter::create() { diff --git a/bolt/lib/Passes/IndirectCallPromotion.cpp b/bolt/lib/Passes/IndirectCallPromotion.cpp index f40f5e7acbf3b8bf0b5aae459011f7f60efeb591..451758161ef5e69ed69608b0b86bf8a60fcc9706 100644 --- a/bolt/lib/Passes/IndirectCallPromotion.cpp +++ b/bolt/lib/Passes/IndirectCallPromotion.cpp @@ -460,7 +460,7 @@ IndirectCallPromotion::maybeGetHotJumpTableTargets(BinaryBasicBlock &BB, if (AccessInfo.MemoryObject) { // Deal with bad/stale data - if (!AccessInfo.MemoryObject->getName().startswith( + if (!AccessInfo.MemoryObject->getName().starts_with( "JUMP_TABLE/" + Function.getOneName().str())) return JumpTableInfoType(); Index = diff --git a/bolt/lib/Passes/ReorderData.cpp b/bolt/lib/Passes/ReorderData.cpp index dc89b383552aba7224cd145993d73c5928d6bdc9..3a6654cf1e0b560e0ed6063811a329d96d693a92 100644 --- a/bolt/lib/Passes/ReorderData.cpp +++ b/bolt/lib/Passes/ReorderData.cpp @@ -408,14 +408,14 @@ bool ReorderData::markUnmoveableSymbols(BinaryContext &BC, // suffix in another. auto isPrivate = [&](const BinaryData *BD) { auto Prefix = std::string("PG") + BC.AsmInfo->getPrivateGlobalPrefix(); - return BD->getName().startswith(Prefix.str()); + return BD->getName().starts_with(Prefix.str()); }; auto Range = BC.getBinaryDataForSection(Section); bool FoundUnmoveable = false; for (auto Itr = Range.begin(); Itr != Range.end(); ++Itr) { BinaryData *Next = std::next(Itr) != Range.end() ? std::next(Itr)->second : nullptr; - if (Itr->second->getName().startswith("PG.")) { + if (Itr->second->getName().starts_with("PG.")) { BinaryData *Prev = Itr != Range.begin() ? std::prev(Itr)->second : nullptr; bool PrevIsPrivate = Prev && isPrivate(Prev); diff --git a/bolt/lib/Passes/ShrinkWrapping.cpp b/bolt/lib/Passes/ShrinkWrapping.cpp index 2dd57f3bbf3d25b6939c31ae3d1e10826abafdb4..d7b25c1279dc8b25b6aeebc97ebf34df69a0e496 100644 --- a/bolt/lib/Passes/ShrinkWrapping.cpp +++ b/bolt/lib/Passes/ShrinkWrapping.cpp @@ -1416,12 +1416,12 @@ bool ShrinkWrapping::foldIdenticalSplitEdges() { bool Changed = false; for (auto Iter = BF.begin(); Iter != BF.end(); ++Iter) { BinaryBasicBlock &BB = *Iter; - if (!BB.getName().startswith(".LSplitEdge")) + if (!BB.getName().starts_with(".LSplitEdge")) continue; for (BinaryBasicBlock &RBB : llvm::reverse(BF)) { if (&RBB == &BB) break; - if (!RBB.getName().startswith(".LSplitEdge") || !RBB.isValid() || + if (!RBB.getName().starts_with(".LSplitEdge") || !RBB.isValid() || !isIdenticalSplitEdgeBB(BC, *Iter, RBB)) continue; assert(RBB.pred_size() == 1 && "Invalid split edge BB"); diff --git a/bolt/lib/Passes/SplitFunctions.cpp b/bolt/lib/Passes/SplitFunctions.cpp index d9f5da3e3bcab568b28f34b12143f14971d67033..5de07597300483a72e6fbfb1acd8a5f0c9146fd8 100644 --- a/bolt/lib/Passes/SplitFunctions.cpp +++ b/bolt/lib/Passes/SplitFunctions.cpp @@ -175,8 +175,12 @@ struct SplitCacheDirected final : public SplitStrategy { void fragment(const BlockIt Start, const BlockIt End) override { BasicBlockOrder BlockOrder(Start, End); BinaryFunction &BF = *BlockOrder.front()->getFunction(); + // No need to re-split small functions. + if (BlockOrder.size() <= 2) + return; size_t BestSplitIndex = findSplitIndex(BF, BlockOrder); + assert(BestSplitIndex < BlockOrder.size()); // Assign fragments based on the computed best split index. // All basic blocks with index up to the best split index become hot. @@ -200,10 +204,12 @@ private: }; struct SplitScore { - size_t SplitIndex; + size_t SplitIndex = size_t(-1); size_t HotSizeReduction = 0; double LocalScore = 0; double CoverCallScore = 0; + + double sum() const { return LocalScore + CoverCallScore; } }; // Auxiliary variables used by the algorithm. @@ -303,7 +309,7 @@ private: const size_t SplitIndex) { assert(SplitIndex < BlockOrder.size() && "Invalid split index"); - // Update function layout assuming hot-warm splitting at SplitIndex + // Update function layout assuming hot-warm splitting at SplitIndex. for (size_t Index = 0; Index < BlockOrder.size(); Index++) { BinaryBasicBlock *BB = BlockOrder[Index]; if (BB->getFragmentNum() == FragmentNum::cold()) @@ -319,8 +325,8 @@ private: // Populate BB.OutputAddressRange with estimated new start and end addresses // and compute the old end address of the hot section and the new end // address of the hot section. - size_t OldHotEndAddr; - size_t NewHotEndAddr; + size_t OldHotEndAddr{0}; + size_t NewHotEndAddr{0}; size_t CurrentAddr = BBOffsets[BlockOrder[0]]; for (BinaryBasicBlock *BB : BlockOrder) { // We only care about new addresses of blocks in hot/warm. @@ -492,20 +498,15 @@ private: } /// Compute the split score of splitting a function at a given index. - /// The split score consists of local score and cover score. Cover call score - /// is expensive to compute. As a result, we pass in a \p ReferenceScore and - /// compute cover score only when the local score exceeds that in the - /// ReferenceScore or that the size reduction of the hot fragment is larger - /// than that achieved by the split index of the ReferenceScore. This function - /// returns \p Score of SplitScore type. It contains the local score and cover - /// score (if computed) of the current splitting index. For easier book - /// keeping and comparison, it also stores the split index and the resulting - /// reduction in hot fragment size. + /// The split score consists of local score and cover score. This function + /// returns \p Score of SplitScore type. It contains the local score and + /// cover score of the current splitting index. For easier book keeping and + /// comparison, it also stores the split index and the resulting reduction + /// in hot fragment size. SplitScore computeSplitScore(const BinaryFunction &BF, const BasicBlockOrder &BlockOrder, const size_t SplitIndex, - const std::vector &CoverCalls, - const SplitScore &ReferenceScore) { + const std::vector &CoverCalls) { // Populate BinaryBasicBlock::OutputAddressRange with estimated // new start and end addresses after hot-warm splitting at SplitIndex. size_t OldHotEnd; @@ -533,47 +534,74 @@ private: // increamented in place. computeJumpScore(BlockOrder, SplitIndex, Score); - // There is no need to compute CoverCallScore if we have already found - // another split index with a bigger LocalScore and bigger HotSizeReduction. - if (Score.LocalScore <= ReferenceScore.LocalScore && - Score.HotSizeReduction <= ReferenceScore.HotSizeReduction) - return Score; - // Compute CoverCallScore and store in Score in place. computeCoverCallScore(BlockOrder, SplitIndex, CoverCalls, Score); return Score; } + /// Find the most likely successor of a basic block when it has one or two + /// successors. Return nullptr otherwise. + const BinaryBasicBlock *getMostLikelySuccessor(const BinaryBasicBlock *BB) { + if (BB->succ_size() == 1) + return BB->getSuccessor(); + if (BB->succ_size() == 2) { + uint64_t TakenCount = BB->getTakenBranchInfo().Count; + assert(TakenCount != BinaryBasicBlock::COUNT_NO_PROFILE); + uint64_t NonTakenCount = BB->getFallthroughBranchInfo().Count; + assert(NonTakenCount != BinaryBasicBlock::COUNT_NO_PROFILE); + if (TakenCount > NonTakenCount) + return BB->getConditionalSuccessor(true); + else if (TakenCount < NonTakenCount) + return BB->getConditionalSuccessor(false); + } + return nullptr; + } + /// Find the best index for splitting. The returned value is the index of the /// last hot basic block. Hence, "no splitting" is equivalent to returning the /// value which is one less than the size of the function. size_t findSplitIndex(const BinaryFunction &BF, const BasicBlockOrder &BlockOrder) { + assert(BlockOrder.size() > 2); // Find all function calls that can be shortened if we move blocks of the // current function to warm/cold const std::vector CoverCalls = extractCoverCalls(BF); - // Try all possible split indices (blocks with Index <= SplitIndex are in - // hot) and find the one maximizing the splitting score. + // Find the existing hot-cold splitting index. + size_t HotColdIndex = 0; + while (HotColdIndex + 1 < BlockOrder.size()) { + if (BlockOrder[HotColdIndex + 1]->getFragmentNum() == FragmentNum::cold()) + break; + HotColdIndex++; + } + assert(HotColdIndex + 1 == BlockOrder.size() || + (BlockOrder[HotColdIndex]->getFragmentNum() == FragmentNum::main() && + BlockOrder[HotColdIndex + 1]->getFragmentNum() == + FragmentNum::cold())); + + // Try all possible split indices up to HotColdIndex (blocks that have + // Index <= SplitIndex are in hot) and find the one maximizing the + // splitting score. SplitScore BestScore; - double BestScoreSum = -1.0; - SplitScore ReferenceScore; - for (size_t Index = 0; Index < BlockOrder.size(); Index++) { + for (size_t Index = 0; Index <= HotColdIndex; Index++) { const BinaryBasicBlock *LastHotBB = BlockOrder[Index]; - // No need to keep cold blocks in the hot section. - if (LastHotBB->getFragmentNum() == FragmentNum::cold()) - break; + assert(LastHotBB->getFragmentNum() != FragmentNum::cold()); + + // Do not break jump to the most likely successor. + if (Index + 1 < BlockOrder.size() && + BlockOrder[Index + 1] == getMostLikelySuccessor(LastHotBB)) + continue; + const SplitScore Score = - computeSplitScore(BF, BlockOrder, Index, CoverCalls, ReferenceScore); - double ScoreSum = Score.LocalScore + Score.CoverCallScore; - if (ScoreSum > BestScoreSum) { - BestScoreSum = ScoreSum; + computeSplitScore(BF, BlockOrder, Index, CoverCalls); + if (Score.sum() > BestScore.sum()) BestScore = Score; - } - if (Score.LocalScore > ReferenceScore.LocalScore) - ReferenceScore = Score; } + // If we don't find a good splitting point, fallback to the original one. + if (BestScore.SplitIndex == size_t(-1)) + return HotColdIndex; + return BestScore.SplitIndex; } }; diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp index 0b306b9965cc3dfb50bd3ddc3cf8109c3b6b006f..be1e348b338f0f025675bd0b844a68f3c412a4b9 100644 --- a/bolt/lib/Profile/DataAggregator.cpp +++ b/bolt/lib/Profile/DataAggregator.cpp @@ -1915,7 +1915,7 @@ DataAggregator::parseMMapEvent() { // PERF_RECORD_MMAP2 /: [() .*]: .* StringRef FileName = Line.rsplit(FieldSeparator).second; - if (FileName.startswith("//") || FileName.startswith("[")) { + if (FileName.starts_with("//") || FileName.starts_with("[")) { consumeRestOfLine(); return std::make_pair(StringRef(), ParsedInfo); } @@ -2168,7 +2168,7 @@ DataAggregator::getFileNameForBuildID(StringRef FileBuildID) { continue; } - if (IDPair->second.startswith(FileBuildID)) { + if (IDPair->second.starts_with(FileBuildID)) { FileName = sys::path::filename(IDPair->first); break; } diff --git a/bolt/lib/Profile/DataReader.cpp b/bolt/lib/Profile/DataReader.cpp index 3d4db6feb51a72eb53ca287fe1c9a5fd0229b45d..aa21eb121ad65256695dfff0318058879c0b203c 100644 --- a/bolt/lib/Profile/DataReader.cpp +++ b/bolt/lib/Profile/DataReader.cpp @@ -55,7 +55,7 @@ bool hasVolatileName(const BinaryFunction &BF) { /// Return standard escaped name of the function possibly renamed by BOLT. std::string normalizeName(StringRef NameRef) { // Strip "PG." prefix used for globalized locals. - NameRef = NameRef.startswith("PG.") ? NameRef.substr(2) : NameRef; + NameRef = NameRef.starts_with("PG.") ? NameRef.substr(2) : NameRef; return getEscapedName(NameRef); } diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp index ade562ef6fb11162cc52eda683ab3c8179dcfa5c..a4a401fd3cabf40278975d74b5713cd6d3670824 100644 --- a/bolt/lib/Profile/YAMLProfileReader.cpp +++ b/bolt/lib/Profile/YAMLProfileReader.cpp @@ -39,7 +39,7 @@ namespace bolt { bool YAMLProfileReader::isYAML(const StringRef Filename) { if (auto MB = MemoryBuffer::getFileOrSTDIN(Filename)) { StringRef Buffer = (*MB)->getBuffer(); - return Buffer.startswith("---\n"); + return Buffer.starts_with("---\n"); } else { report_error(Filename, MB.getError()); } diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 1cc07c1cc9f76a21d90ddfe048636968f3ff6d2c..05fb3e8fafe2f7cbfd9162160ef4d9a157b7c63e 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -554,7 +554,7 @@ void DWARFRewriter::addStringHelper(DIEBuilder &DIEBldr, DIE &Die, const DWARFUnit &Unit, DIEValue &DIEAttrInfo, StringRef Str) { uint32_t NewOffset = StrWriter->addString(Str); - if (Unit.getVersion() == 5) { + if (Unit.getVersion() >= 5) { StrOffstsWriter->updateAddressMap(DIEAttrInfo.getDIEInteger().getValue(), NewOffset); return; @@ -696,9 +696,6 @@ void DWARFRewriter::updateDebugInfo() { std::optional SplitCU; std::optional RangesBase; std::optional DWOId = Unit->getDWOId(); - if (Unit->getVersion() >= 5) - StrOffstsWriter->initialize(Unit->getStringOffsetSection(), - Unit->getStringOffsetsTableContribution()); if (DWOId) SplitCU = BC.getDWOCU(*DWOId); DebugLocWriter *DebugLocWriter = createRangeLocList(*Unit); @@ -753,7 +750,7 @@ void DWARFRewriter::updateDebugInfo() { }; DIEBuilder DIEBlder(BC.DwCtx.get()); - DIEBlder.buildTypeUnits(); + DIEBlder.buildTypeUnits(StrOffstsWriter.get()); SmallVector OutBuffer; std::unique_ptr ObjOS = std::make_unique(OutBuffer); diff --git a/bolt/lib/Rewrite/ExecutableFileMemoryManager.cpp b/bolt/lib/Rewrite/ExecutableFileMemoryManager.cpp index aa5c8344aa6f5428202050e558ad49dc6886ad91..041d0d8c2b274fecff51d7f20b4348ffac58422c 100644 --- a/bolt/lib/Rewrite/ExecutableFileMemoryManager.cpp +++ b/bolt/lib/Rewrite/ExecutableFileMemoryManager.cpp @@ -120,7 +120,7 @@ void ExecutableFileMemoryManager::updateSection( } if (!IsCode && (SectionName == ".strtab" || SectionName == ".symtab" || - SectionName == "" || SectionName.startswith(".rela."))) + SectionName == "" || SectionName.starts_with(".rela."))) return; SmallVector Buf; @@ -139,7 +139,7 @@ void ExecutableFileMemoryManager::updateSection( } BinarySection *Section = nullptr; - if (!OrgSecPrefix.empty() && SectionName.startswith(OrgSecPrefix)) { + if (!OrgSecPrefix.empty() && SectionName.starts_with(OrgSecPrefix)) { // Update the original section contents. ErrorOr OrgSection = BC.getUniqueSectionByName(SectionName.substr(OrgSecPrefix.length())); diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 1e8ca569682f712cd4a2ad3cbabda406d8b4f277..a95b1650753cfdc73584080dff0a687ecce0d175 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -538,7 +538,7 @@ Error RewriteInstance::discoverStorage() { if (!opts::HeatmapMode && !(opts::AggregateOnly && BAT->enabledFor(InputFile)) && - (SectionName.startswith(getOrgSecPrefix()) || + (SectionName.starts_with(getOrgSecPrefix()) || SectionName == getBOLTTextSectionName())) return createStringError( errc::function_not_supported, @@ -778,12 +778,12 @@ void RewriteInstance::discoverFileObjects() { std::unordered_map SymbolToFileName; for (const ELFSymbolRef &Symbol : InputFile->symbols()) { Expected NameOrError = Symbol.getName(); - if (NameOrError && NameOrError->startswith("__asan_init")) { + if (NameOrError && NameOrError->starts_with("__asan_init")) { errs() << "BOLT-ERROR: input file was compiled or linked with sanitizer " "support. Cannot optimize.\n"; exit(1); } - if (NameOrError && NameOrError->startswith("__llvm_coverage_mapping")) { + if (NameOrError && NameOrError->starts_with("__llvm_coverage_mapping")) { errs() << "BOLT-ERROR: input file was compiled or linked with coverage " "support. Cannot optimize.\n"; exit(1); @@ -938,9 +938,10 @@ void RewriteInstance::discoverFileObjects() { /// It is possible we are seeing a globalized local. LLVM might treat it as /// a local if it has a "private global" prefix, e.g. ".L". Thus we have to /// change the prefix to enforce global scope of the symbol. - std::string Name = SymName.startswith(BC->AsmInfo->getPrivateGlobalPrefix()) - ? "PG" + std::string(SymName) - : std::string(SymName); + std::string Name = + SymName.starts_with(BC->AsmInfo->getPrivateGlobalPrefix()) + ? "PG" + std::string(SymName) + : std::string(SymName); // Disambiguate all local symbols before adding to symbol table. // Since we don't know if we will see a global with the same name, @@ -2723,8 +2724,8 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection, BD->nameStartsWith(SymbolName) || BD->nameStartsWith("PG" + SymbolName) || (BD->nameStartsWith("ANONYMOUS") && - (BD->getSectionName().startswith(".plt") || - BD->getSectionName().endswith(".plt")))) && + (BD->getSectionName().starts_with(".plt") || + BD->getSectionName().ends_with(".plt")))) && "BOLT symbol names of all non-section relocations must match up " "with symbol names referenced in the relocation"); @@ -2740,7 +2741,7 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection, // in relocation sections can get through here too, from .plt. assert( (IsAArch64 || BC->isRISCV() || IsSectionRelocation || - BC->getSectionNameForAddress(SymbolAddress)->startswith(".plt")) && + BC->getSectionNameForAddress(SymbolAddress)->starts_with(".plt")) && "known symbols should not resolve to anonymous locals"); if (IsSectionRelocation) { @@ -2757,7 +2758,7 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection, Name = SymbolName; } else { if (StringRef(SymbolName) - .startswith(BC->AsmInfo->getPrivateGlobalPrefix())) + .starts_with(BC->AsmInfo->getPrivateGlobalPrefix())) Name = NR.uniquify("PG" + SymbolName); else Name = NR.uniquify(SymbolName); @@ -3464,8 +3465,8 @@ std::vector RewriteInstance::getCodeSections() { // ".text.cold.T", ".text.cold.T-1", ... ".text.cold.1", ".text.cold" // - if opts::HotFunctionsAtEnd is false, we want order // ".text.cold", ".text.cold.1", ... ".text.cold.T-1", ".text.cold.T" - if (A->getName().startswith(BC->getColdCodeSectionName()) && - B->getName().startswith(BC->getColdCodeSectionName())) { + if (A->getName().starts_with(BC->getColdCodeSectionName()) && + B->getName().starts_with(BC->getColdCodeSectionName())) { if (A->getName().size() != B->getName().size()) return (opts::HotFunctionsAtEnd) ? (A->getName().size() > B->getName().size()) @@ -5653,16 +5654,16 @@ bool RewriteInstance::willOverwriteSection(StringRef SectionName) { } bool RewriteInstance::isDebugSection(StringRef SectionName) { - if (SectionName.startswith(".debug_") || SectionName.startswith(".zdebug_") || - SectionName == ".gdb_index" || SectionName == ".stab" || - SectionName == ".stabstr") + if (SectionName.starts_with(".debug_") || + SectionName.starts_with(".zdebug_") || SectionName == ".gdb_index" || + SectionName == ".stab" || SectionName == ".stabstr") return true; return false; } bool RewriteInstance::isKSymtabSection(StringRef SectionName) { - if (SectionName.startswith("__ksymtab")) + if (SectionName.starts_with("__ksymtab")) return true; return false; diff --git a/bolt/test/AArch64/ifunc.c b/bolt/test/AArch64/ifunc.c index 8edb913ee70d5c0f70cdbe7c4eb19eb2c794d945..c8c5c7c29d4a56d7e46ef33ef0406a76a7284a53 100644 --- a/bolt/test/AArch64/ifunc.c +++ b/bolt/test/AArch64/ifunc.c @@ -6,7 +6,7 @@ // RUN: -o %t.O0.exe -Wl,-q // RUN: llvm-bolt %t.O0.exe -o %t.O0.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ -// RUN: FileCheck --check-prefix=O0_CHECK %s +// RUN: FileCheck --check-prefix=CHECK %s // RUN: llvm-readelf -aW %t.O0.bolt.exe | \ // RUN: FileCheck --check-prefix=REL_CHECK %s @@ -18,7 +18,7 @@ // RUN: FileCheck --check-prefix=NON_DYN_CHECK %s // RUN: llvm-bolt %t.O3_nopie.exe -o %t.O3_nopie.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ -// RUN: FileCheck --check-prefix=O3_CHECK %s +// RUN: FileCheck --check-prefix=CHECK %s // RUN: llvm-readelf -aW %t.O3_nopie.bolt.exe | \ // RUN: FileCheck --check-prefix=REL_CHECK %s @@ -29,7 +29,7 @@ // RUN: -o %t.O3_pie.exe -Wl,-q // RUN: llvm-bolt %t.O3_pie.exe -o %t.O3_pie.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ -// RUN: FileCheck --check-prefix=O3_CHECK %s +// RUN: FileCheck --check-prefix=CHECK %s // RUN: llvm-readelf -aW %t.O3_pie.bolt.exe | \ // RUN: FileCheck --check-prefix=REL_CHECK %s @@ -39,14 +39,13 @@ // RUN: -T %p/Inputs/iplt.ld -o %t.iplt_O3_pie.exe -Wl,-q // RUN: llvm-bolt %t.iplt_O3_pie.exe -o %t.iplt_O3_pie.bolt.exe \ // RUN: --print-disasm --print-only=_start | \ -// RUN: FileCheck --check-prefix=O3_CHECK %s +// RUN: FileCheck --check-prefix=CHECK %s // RUN: llvm-readelf -aW %t.iplt_O3_pie.bolt.exe | \ // RUN: FileCheck --check-prefix=REL_CHECK %s // NON_DYN_CHECK-NOT: DYNAMIC -// O0_CHECK: adr x{{[0-9]+}}, ifoo -// O3_CHECK: b "{{resolver_foo|ifoo}}{{.*}}@PLT" +// CHECK: {{(bl? "(resolver_foo|ifoo).*@PLT"|adr x[0-9]+, ifoo)}} // REL_CHECK: R_AARCH64_IRELATIVE [[#%x,REL_SYMB_ADDR:]] // REL_CHECK: [[#REL_SYMB_ADDR]] {{.*}} FUNC {{.*}} resolver_foo diff --git a/bolt/test/RISCV/call-annotations.s b/bolt/test/RISCV/call-annotations.s index 1a8ac1571f0be240999aa78c25479cd45cfe95d5..ff99e0f1dfd84844c5eaf4b5e54d8894253d3526 100644 --- a/bolt/test/RISCV/call-annotations.s +++ b/bolt/test/RISCV/call-annotations.s @@ -16,13 +16,13 @@ f: // CHECK-LABEL: Binary Function "_start" after building cfg { // CHECK: auipc ra, f -// CHECK-NEXT: jalr ra, -4(ra) # Offset: 4 +// CHECK-NEXT: jalr ra, -0x4(ra) # Offset: 4 // CHECK-NEXT: jal ra, f # Offset: 8 // CHECK-NEXT: jal zero, f # TAILCALL # Offset: 12 // CHECK-LABEL: Binary Function "long_tail" after building cfg { // CHECK: auipc t1, f -// CHECK-NEXT: jalr zero, -24(t1) # TAILCALL # Offset: 8 +// CHECK-NEXT: jalr zero, -0x18(t1) # TAILCALL # Offset: 8 // CHECK-LABEL: Binary Function "compressed_tail" after building cfg { // CHECK: jr a0 # TAILCALL # Offset: 0 diff --git a/bolt/test/RISCV/relax.s b/bolt/test/RISCV/relax.s index 01682e4405b71598512a2ba6322b6cb6205832d4..bf9287e1d0d85a456e44c36f8b2e6598c88b8d14 100644 --- a/bolt/test/RISCV/relax.s +++ b/bolt/test/RISCV/relax.s @@ -7,7 +7,7 @@ // CHECK: Binary Function "_start" after building cfg { // CHECK: jal ra, near_f // CHECK-NEXT: auipc ra, far_f@plt -// CHECK-NEXT: jalr ra, 12(ra) +// CHECK-NEXT: jalr ra, 0xc(ra) // CHECK-NEXT: j near_f // CHECK: Binary Function "_start" after fix-riscv-calls { @@ -17,8 +17,8 @@ // OBJDUMP: 0000000000600000 <_start>: // OBJDUMP-NEXT: jal 0x600040 -// OBJDUMP-NEXT: auipc ra, 512 -// OBJDUMP-NEXT: jalr 124(ra) +// OBJDUMP-NEXT: auipc ra, 0x200 +// OBJDUMP-NEXT: jalr 0x7c(ra) // OBJDUMP-NEXT: j 0x600040 // OBJDUMP: 0000000000600040 : // OBJDUMP: 0000000000800080 : diff --git a/bolt/test/RISCV/reloc-tls.s b/bolt/test/RISCV/reloc-tls.s index a4c7bd06de907cefeb108aec2fd3262fe998f727..d6c8e492cab5d9ae850341dabe15b28e9f64e387 100644 --- a/bolt/test/RISCV/reloc-tls.s +++ b/bolt/test/RISCV/reloc-tls.s @@ -4,10 +4,10 @@ // RUN: | FileCheck %s // CHECK-LABEL: Binary Function "tls_le{{.*}}" after building cfg { -// CHECK: lui a5, 0 +// CHECK: lui a5, 0x0 // CHECK-NEXT: add a5, a5, tp -// CHECK-NEXT: lw t0, 0(a5) -// CHECK-NEXT: sw t0, 0(a5) +// CHECK-NEXT: lw t0, 0x0(a5) +// CHECK-NEXT: sw t0, 0x0(a5) // CHECK-LABEL: Binary Function "tls_ie" after building cfg { // CHECK-LABEL: .LBB01 diff --git a/bolt/test/RISCV/reorder-blocks-reverse.s b/bolt/test/RISCV/reorder-blocks-reverse.s index 2da34844a5a8412d47c5d6483744a173a1257a40..6909fde59a4801945f04f133e8fe9804fc892ec0 100644 --- a/bolt/test/RISCV/reorder-blocks-reverse.s +++ b/bolt/test/RISCV/reorder-blocks-reverse.s @@ -23,9 +23,9 @@ _start: // CHECK-NEXT: {{.*}}00: beq t0, t1, {{.*}} <_start+0x10> // CHECK-NEXT: {{.*}}04: j {{.*}} <_start+0x16> // CHECK-NEXT: {{.*}}08: ret -// CHECK-NEXT: {{.*}}0a: li a0, 6 +// CHECK-NEXT: {{.*}}0a: li a0, 0x6 // CHECK-NEXT: {{.*}}0c: j {{.*}} <_start+0x8> -// CHECK-NEXT: {{.*}}10: li a0, 5 +// CHECK-NEXT: {{.*}}10: li a0, 0x5 // CHECK-NEXT: {{.*}}12: j {{.*}} <_start+0x8> // CHECK-NEXT: {{.*}}16: beq t0, t2, {{.*}} <_start+0xa> // CHECK-NEXT: {{.*}}1a: j {{.*}} <_start+0x10> diff --git a/bolt/test/RISCV/tls-le-gnu-ld.test b/bolt/test/RISCV/tls-le-gnu-ld.test index c3ff08b30ee60dd920e242aa39c68c2aec114d6e..06e5bc0b5c82a003914a29f276e01a679809623c 100644 --- a/bolt/test/RISCV/tls-le-gnu-ld.test +++ b/bolt/test/RISCV/tls-le-gnu-ld.test @@ -7,5 +7,5 @@ // RUN: | FileCheck %s // CHECK: Binary Function "_start" after building cfg { -// CHECK: lw t0, 0(tp) -// CHECK-NEXT: sw t0, 0(tp) +// CHECK: lw t0, 0x0(tp) +// CHECK-NEXT: sw t0, 0x0(tp) diff --git a/bolt/test/X86/Inputs/dwarf5-basic-cu.s b/bolt/test/X86/Inputs/dwarf5-basic-cu.s new file mode 100644 index 0000000000000000000000000000000000000000..a57803ea05ebc50f02d6223e08dd7bdc8773fd6b --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf5-basic-cu.s @@ -0,0 +1,160 @@ +# clang++ main.cpp -g2 -gdwarf-5 -gno-pubnames -fdebug-types-section -S +# int main() { +# return 0; +# } + .text + .file "main.cpp" + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .file 0 "/home" "main.cpp" md5 0xbb12fec8d002b1f0e06f7dee4604c6cc + .loc 0 1 0 # main.cpp:1:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl $0, -4(%rbp) +.Ltmp0: + .loc 0 2 3 prologue_end # main.cpp:2:3 + xorl %eax, %eax + .loc 0 2 3 epilogue_begin is_stmt 0 # main.cpp:2:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x2b DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0xf DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 50 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 24 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "/home" # string offset=113 +.Linfo_string3: + .asciz "main" # string offset=151 +.Linfo_string4: + .asciz "int" # string offset=156 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .ident "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/Inputs/dwarf5-types-no-cu.s b/bolt/test/X86/Inputs/dwarf5-types-no-cu.s new file mode 100644 index 0000000000000000000000000000000000000000..56fcd1542a0a538f22b1c8372d32987a4ced2723 --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf5-types-no-cu.s @@ -0,0 +1,281 @@ +# clang++ helper.cpp -g2 -gdwarf-5 -gno-pubnames -fdebug-types-section -S -o helperTypes.s +# struct Foo1 { +# char a1; +# char a2; +# char a3; +# }; +# +# struct Foo2 { +# int b1; +# int b2; +# }; +# +# Foo1 f1; +# Foo2 f2; + +# Manually removed Compile Unit .debug_info section. + + .text + .file "helper.cpp" + .file 0 "/home" "helper.cpp" md5 0xd58ef77d520bf2e6491a2e387a3501f1 + .section .debug_info,"G",@progbits,5391472263833448044,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad 5391472263833448044 # Type Signature + .long 35 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x32 DW_TAG_type_unit + .short 33 # DW_AT_language + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x23:0x22 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 8 # DW_AT_name + .byte 3 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member + .byte 4 # DW_AT_name + .long 69 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 3 # Abbrev [3] 0x32:0x9 DW_TAG_member + .byte 6 # DW_AT_name + .long 69 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 1 # DW_AT_data_member_location + .byte 3 # Abbrev [3] 0x3b:0x9 DW_TAG_member + .byte 7 # DW_AT_name + .long 69 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .byte 2 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x45:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_info,"G",@progbits,5322170643381124694,comdat +.Ltu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad 5322170643381124694 # Type Signature + .long 35 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x29 DW_TAG_type_unit + .short 33 # DW_AT_language + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x23:0x19 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 13 # DW_AT_name + .byte 8 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member + .byte 10 # DW_AT_name + .long 60 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 3 # Abbrev [3] 0x32:0x9 DW_TAG_member + .byte 12 # DW_AT_name + .long 60 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .byte 4 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x3c:0x4 DW_TAG_base_type + .byte 11 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .type f1,@object # @f1 + .bss + .globl f1 +f1: + .zero 3 + .size f1, 3 + + .type f2,@object # @f2 + .globl f2 + .p2align 2, 0x0 +f2: + .zero 8 + .size f2, 8 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 13 # DW_TAG_member + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 56 # DW_AT_data_member_location + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_str_offsets,"",@progbits + .long 60 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" # string offset=0 +.Linfo_string1: + .asciz "helper.cpp" # string offset=104 +.Linfo_string2: + .asciz "/home" # string offset=115 +.Linfo_string3: + .asciz "f1" # string offset=153 +.Linfo_string4: + .asciz "a1" # string offset=156 +.Linfo_string5: + .asciz "char" # string offset=159 +.Linfo_string6: + .asciz "a2" # string offset=164 +.Linfo_string7: + .asciz "a3" # string offset=167 +.Linfo_string8: + .asciz "Foo1" # string offset=170 +.Linfo_string9: + .asciz "f2" # string offset=175 +.Linfo_string10: + .asciz "b1" # string offset=178 +.Linfo_string11: + .asciz "int" # string offset=181 +.Linfo_string12: + .asciz "b2" # string offset=185 +.Linfo_string13: + .asciz "Foo2" # string offset=188 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .long .Linfo_string12 + .long .Linfo_string13 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad f1 + .quad f2 +.Ldebug_addr_end0: + .ident "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/cdsplit-call-scale.s b/bolt/test/X86/cdsplit-call-scale.s index 5b4f92832624cd5eb9e2d1f1ffdd601c9893cbf8..5701d9e6dfd6965abcdcae3696eccf1c019e4164 100644 --- a/bolt/test/X86/cdsplit-call-scale.s +++ b/bolt/test/X86/cdsplit-call-scale.s @@ -2,8 +2,9 @@ # When -call-scale=0.0, the tested function is 2-way splitted. # When -call-scale=1.0, the tested function is 3-way splitted with 5 blocks # in warm because of the increased benefit of shortening the call edges. -# When -call-scale=1000.0, the tested function is 3-way splitted with 7 blocks -# in warm because of the strong benefit of shortening the call edges. +# When -call-scale=1000.0, the tested function is still 3-way splitted with +# 5 blocks in warm because cdsplit does not allow hot-warm splitting to break +# a fall through branch from a basic block to its most likely successor. # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata @@ -39,12 +40,10 @@ # MEDINCENTIVE: {{^\.Ltmp5}} # HIGHINCENTIVE: Binary Function "chain" after split-functions -# HIGHINCENTIVE: {{^\.LBB00}} +# HIGHINCENTIVE: {{^\.Ltmp1}} # HIGHINCENTIVE: ------- HOT-COLD SPLIT POINT ------- # HIGHINCENTIVE: {{^\.LFT1}} # HIGHINCENTIVE: ------- HOT-COLD SPLIT POINT ------- -# HIGHINCENTIVE: {{^\.LFT0}} -# HIGHINCENTIVE: {{^\.Ltmp1}} # HIGHINCENTIVE: {{^\.Ltmp0}} # HIGHINCENTIVE: {{^\.Ltmp2}} # HIGHINCENTIVE: {{^\.Ltmp3}} diff --git a/bolt/test/X86/dwarf-test-df-logging.test b/bolt/test/X86/dwarf-test-df-logging.test index ca5e578a0845fd76c525d345851ac54233fdc408..6126e9628a31a99112b98466156ec5005e8d72dd 100644 --- a/bolt/test/X86/dwarf-test-df-logging.test +++ b/bolt/test/X86/dwarf-test-df-logging.test @@ -6,7 +6,7 @@ ; RUN: -split-dwarf-file=main.dwo -o main.o ; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-dualcu-helper.s \ ; RUN: -split-dwarf-file=helper.dwo -o helper.o -; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe +; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe -fno-pic -no-pie ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections | FileCheck -check-prefix=BOLT %s ; BOLT: BOLT-INFO: processing split DWARF diff --git a/bolt/test/X86/dwarf4-df-dualcu.test b/bolt/test/X86/dwarf4-df-dualcu.test index 5564d9ff26450472f672b16fee69951b38e53bf7..91b3e9e4cf0926c69eb894ae7c651571b111bdd0 100644 --- a/bolt/test/X86/dwarf4-df-dualcu.test +++ b/bolt/test/X86/dwarf4-df-dualcu.test @@ -5,7 +5,7 @@ ; RUN: -split-dwarf-file=main.dwo -o main.o ; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-dualcu-helper.s \ ; RUN: -split-dwarf-file=helper.dwo -o helper.o -; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe +; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe -fno-pic -no-pie ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --always-convert-to-ranges ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe | FileCheck -check-prefix=PRE-BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-ranges main.exe.bolt &> %t/foo.txt diff --git a/bolt/test/X86/dwarf4-split-dwarf-no-address.test b/bolt/test/X86/dwarf4-split-dwarf-no-address.test index 5baef9238e9047dd37cdccaa9e42cf38c2676ae4..753fad06eb069fd477aaebe8ea4e77f5f331a64e 100644 --- a/bolt/test/X86/dwarf4-split-dwarf-no-address.test +++ b/bolt/test/X86/dwarf4-split-dwarf-no-address.test @@ -5,7 +5,7 @@ ; RUN: --filetype=obj %p/Inputs/dwarf4-split-dwarf-no-address-main.s -o=main.o ; RUN: llvm-mc --split-dwarf-file=helper.dwo --triple=x86_64-unknown-linux-gnu \ ; RUN: --filetype=obj %p/Inputs/dwarf4-split-dwarf-no-address-helper.s -o=helper.o -; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o helper.o -o main.exe +; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o helper.o -o main.exe -fno-pic -no-pie ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt | FileCheck -check-prefix=BOLT %s diff --git a/bolt/test/X86/dwarf5-df-dualcu.test b/bolt/test/X86/dwarf5-df-dualcu.test index 15d458d1c0251fd21e5cdc48dee0a5f9171c8cf6..deaeea03669081f670e52d529428470a3f87af23 100644 --- a/bolt/test/X86/dwarf5-df-dualcu.test +++ b/bolt/test/X86/dwarf5-df-dualcu.test @@ -5,7 +5,7 @@ ; RUN: -split-dwarf-file=main.dwo -o main.o ; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-dualcu-helper.s \ ; RUN: -split-dwarf-file=helper.dwo -o helper.o -; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe +; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o -o main.exe -fno-pic -no-pie ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --always-convert-to-ranges ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe | FileCheck -check-prefix=PRE-BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-addr main.exe.bolt &> %t/foo.txt diff --git a/bolt/test/X86/dwarf5-df-mono-dualcu.test b/bolt/test/X86/dwarf5-df-mono-dualcu.test index a6024997ba72d9bedd96433c970e28688a48a50d..12269287ef132f18fe66b8460cd2aa246674d49d 100644 --- a/bolt/test/X86/dwarf5-df-mono-dualcu.test +++ b/bolt/test/X86/dwarf5-df-mono-dualcu.test @@ -4,7 +4,7 @@ ; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-mono-main.s \ ; RUN: -split-dwarf-file=main.dwo -o main.o ; RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux-gnu %p/Inputs/dwarf5-df-mono-helper.s -o=helper.o -; RUN: %clang %cflags -gdwarf-5 main.o helper.o -o main.exe +; RUN: %clang %cflags -gdwarf-5 main.o helper.o -o main.exe -fno-pic -no-pie ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --always-convert-to-ranges ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe | FileCheck -check-prefix=PRE-BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-addr main.exe.bolt &> %t/foo.txt diff --git a/bolt/test/X86/dwarf5-locaddrx.test b/bolt/test/X86/dwarf5-locaddrx.test index a1d66bb359d27ae72b52e3b16d6a3be1eafe305f..00e15101f85311235f9c27c66e38a48533b118a6 100644 --- a/bolt/test/X86/dwarf5-locaddrx.test +++ b/bolt/test/X86/dwarf5-locaddrx.test @@ -3,7 +3,7 @@ ; RUN: cd %t ; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-locaddrx.s \ ; RUN: -split-dwarf-file=mainlocadddrx.dwo -o mainlocadddrx.o -; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split mainlocadddrx.o -o mainlocadddrx.exe +; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split mainlocadddrx.o -o mainlocadddrx.exe -fno-pic -no-pie ; RUN: llvm-bolt mainlocadddrx.exe -o mainlocadddrx.exe.bolt --update-debug-sections --always-convert-to-ranges ; RUN: llvm-dwarfdump --show-form --verbose --debug-info mainlocadddrx.exe | FileCheck -check-prefix=PRE-BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-addr mainlocadddrx.exe.bolt &> %t/foo.txt diff --git a/bolt/test/X86/dwarf5-type-unit-no-cu-str-offset-table.test b/bolt/test/X86/dwarf5-type-unit-no-cu-str-offset-table.test new file mode 100644 index 0000000000000000000000000000000000000000..21ced6ce687b5c27d15ef04168828a6467036dac --- /dev/null +++ b/bolt/test/X86/dwarf5-type-unit-no-cu-str-offset-table.test @@ -0,0 +1,57 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-basic-cu.s -o %tmain.o +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-types-no-cu.s -o %thelper.o +# RUN: %clang %cflags %tmain.o %thelper.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-dwarfdump --show-form --verbose --debug-str-offsets %t.exe | FileCheck -check-prefix=PRE-BOLT %s +# RUN: llvm-dwarfdump --show-form --verbose --debug-str-offsets %t.bolt | FileCheck -check-prefix=POST-BOLT %s + +## This test checks we correclty re-generate .debug_str_offsets when there are type units that have an offset not shared with CU. + +# PRE-BOLT: .debug_str_offsets contents +# PRE-BOLT-NEXT: Contribution size = 24, Format = DWARF32, Version = 5 +# PRE-BOLT-NEXT: "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" +# PRE-BOLT-NEXT: "main.cpp" +# PRE-BOLT-NEXT: "/home" +# PRE-BOLT-NEXT: "main" +# PRE-BOLT-NEXT: "int" +# PRE-BOLT-NEXT: Contribution size = 60, Format = DWARF32, Version = 5 +# PRE-BOLT-NEXT: "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" +# PRE-BOLT-NEXT: "helper.cpp" +# PRE-BOLT-NEXT: "/home" +# PRE-BOLT-NEXT: "f1" +# PRE-BOLT-NEXT: "a1" +# PRE-BOLT-NEXT: "char" +# PRE-BOLT-NEXT: "a2" +# PRE-BOLT-NEXT: "a3" +# PRE-BOLT-NEXT: "Foo1" +# PRE-BOLT-NEXT: "f2" +# PRE-BOLT-NEXT: "b1" +# PRE-BOLT-NEXT: "int" +# PRE-BOLT-NEXT: "b2" +# PRE-BOLT-NEXT: "Foo2" + +## Checking post bolt +# POST-BOLT: .debug_str_offsets contents +# POST-BOLT-NEXT: Contribution size = 60, Format = DWARF32, Version = 5 +# POST-BOLT-NEXT: "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" +# POST-BOLT-NEXT: "helper.cpp" +# POST-BOLT-NEXT: "/home" +# POST-BOLT-NEXT: "f1" +# POST-BOLT-NEXT: "a1" +# POST-BOLT-NEXT: "char" +# POST-BOLT-NEXT: "a2" +# POST-BOLT-NEXT: "a3" +# POST-BOLT-NEXT: "Foo1" +# POST-BOLT-NEXT: "f2" +# POST-BOLT-NEXT: "b1" +# POST-BOLT-NEXT: "int" +# POST-BOLT-NEXT: "b2" +# POST-BOLT-NEXT: "Foo2" +# POST-BOLT-NEXT: Contribution size = 24, Format = DWARF32, Version = 5 +# POST-BOLT-NEXT: "clang version 18.0.0git (git@github.com:llvm/llvm-project.git 44dc1e0baae7c4b8a02ba06dcf396d3d452aa873)" +# POST-BOLT-NEXT: "main.cpp" +# POST-BOLT-NEXT: "/home" +# POST-BOLT-NEXT: "main" +# POST-BOLT-NEXT: "int" diff --git a/bolt/tools/merge-fdata/merge-fdata.cpp b/bolt/tools/merge-fdata/merge-fdata.cpp index 757f0536616bec25812e517f39637e33fd4454ce..e21aeba73aca29a2154b209e53789114b7299e4a 100644 --- a/bolt/tools/merge-fdata/merge-fdata.cpp +++ b/bolt/tools/merge-fdata/merge-fdata.cpp @@ -253,7 +253,7 @@ bool isYAML(const StringRef Filename) { if (std::error_code EC = MB.getError()) report_error(Filename, EC); StringRef Buffer = MB.get()->getBuffer(); - if (Buffer.startswith("---\n")) + if (Buffer.starts_with("---\n")) return true; return false; } @@ -279,7 +279,7 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { { std::lock_guard Lock(BoltedCollectionMutex); // Check if the string "boltedcollection" is in the first line - if (Buf.startswith("boltedcollection\n")) { + if (Buf.starts_with("boltedcollection\n")) { if (!BoltedCollection.value_or(true)) report_error( Filename, diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp index 7f7af7069c418877bbbe54438fd26bae44c38046..879c0d26d472a8dc83fc7129bcd7158f16e2b62e 100644 --- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp @@ -827,10 +827,10 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( // "IsVisibleInNewNs" matcher. if (AliasQualifiedName != AliasName) { // The alias is defined in some namespace. - assert(StringRef(AliasQualifiedName).endswith("::" + AliasName)); + assert(StringRef(AliasQualifiedName).ends_with("::" + AliasName)); llvm::StringRef AliasNs = StringRef(AliasQualifiedName).drop_back(AliasName.size() + 2); - if (!llvm::StringRef(OldNs).startswith(AliasNs)) + if (!llvm::StringRef(OldNs).starts_with(AliasNs)) continue; } std::string NameWithAliasNamespace = @@ -862,7 +862,7 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( // If the new nested name in the new namespace is the same as it was in the // old namespace, we don't create replacement unless there can be ambiguity. if ((NestedName == ReplaceName && !Conflict) || - (NestedName.startswith("::") && NestedName.drop_front(2) == ReplaceName)) + (NestedName.starts_with("::") && NestedName.drop_front(2) == ReplaceName)) return; // If the reference need to be fully-qualified, add a leading "::" unless // NewNamespace is the global namespace. @@ -891,7 +891,7 @@ void ChangeNamespaceTool::fixTypeLoc( // a typedef type, we need to use the typedef type instead. auto IsInMovedNs = [&](const NamedDecl *D) { if (!llvm::StringRef(D->getQualifiedNameAsString()) - .startswith(OldNamespace + "::")) + .starts_with(OldNamespace + "::")) return false; auto ExpansionLoc = Result.SourceManager->getExpansionLoc(D->getBeginLoc()); if (ExpansionLoc.isInvalid()) diff --git a/clang-tools-extra/clang-include-fixer/IncludeFixerContext.cpp b/clang-tools-extra/clang-include-fixer/IncludeFixerContext.cpp index f6f8404204ba06405ecb9dda2d80a8658c417b20..d7369b162dc10d8d87fc35f313212f819bc42101 100644 --- a/clang-tools-extra/clang-include-fixer/IncludeFixerContext.cpp +++ b/clang-tools-extra/clang-include-fixer/IncludeFixerContext.cpp @@ -28,7 +28,7 @@ std::string createQualifiedNameForReplacement( const find_all_symbols::SymbolInfo &MatchedSymbol) { // No need to add missing qualifiers if SymbolIdentifier has a global scope // operator "::". - if (RawSymbolName.startswith("::")) + if (RawSymbolName.starts_with("::")) return std::string(RawSymbolName); std::string QualifiedName = MatchedSymbol.getQualifiedName(); @@ -42,7 +42,7 @@ std::string createQualifiedNameForReplacement( auto SymbolQualifiers = SplitQualifiers(RawSymbolName); std::string StrippedQualifiers; while (!SymbolQualifiers.empty() && - !llvm::StringRef(QualifiedName).endswith(SymbolQualifiers.back())) { + !llvm::StringRef(QualifiedName).ends_with(SymbolQualifiers.back())) { StrippedQualifiers = "::" + SymbolQualifiers.back().str() + StrippedQualifiers; SymbolQualifiers.pop_back(); diff --git a/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp b/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp index 952c5fdedc291e51b3118c0e6f5c7cbfa6302727..027df3cfb2cc26760cc4289de99823d541da4d63 100644 --- a/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp +++ b/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp @@ -82,7 +82,7 @@ SymbolIndexManager::search(llvm::StringRef Identifier, Identifier.split(Names, "::"); bool IsFullyQualified = false; - if (Identifier.startswith("::")) { + if (Identifier.starts_with("::")) { Names.erase(Names.begin()); // Drop first (empty) element. IsFullyQualified = true; } diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/PathConfig.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/PathConfig.cpp index 503fd60cb4c1b86ffb3b9e3584ad842a37e1c1d5..6d52963370ddd7ce89928b3742611ca017478339 100644 --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/PathConfig.cpp +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/PathConfig.cpp @@ -24,7 +24,7 @@ std::string getIncludePath(const SourceManager &SM, SourceLocation Loc, FilePath = SM.getFilename(Loc); if (FilePath.empty()) return ""; - if (!FilePath.endswith(".inc")) + if (!FilePath.ends_with(".inc")) break; FileID ID = SM.getFileID(Loc); Loc = SM.getIncludeLoc(ID); diff --git a/clang-tools-extra/clang-include-fixer/plugin/IncludeFixerPlugin.cpp b/clang-tools-extra/clang-include-fixer/plugin/IncludeFixerPlugin.cpp index 7908a890fcb63c659804d7a058dc93940601b1c1..ce431d443be4b46aaaabdd8af343adc0f0d6279f 100644 --- a/clang-tools-extra/clang-include-fixer/plugin/IncludeFixerPlugin.cpp +++ b/clang-tools-extra/clang-include-fixer/plugin/IncludeFixerPlugin.cpp @@ -54,9 +54,9 @@ public: // Parse the extra command line args. // FIXME: This is very limited at the moment. for (StringRef Arg : Args) { - if (Arg.startswith("-db=")) + if (Arg.starts_with("-db=")) DB = Arg.substr(strlen("-db=")); - else if (Arg.startswith("-input=")) + else if (Arg.starts_with("-input=")) Input = Arg.substr(strlen("-input=")); } diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp index 565f044778c946397261584fde73454c9549715a..40ac6918faf40786b1add8fb16e1c5933d76ca2e 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp @@ -390,7 +390,7 @@ static CheckersList getAnalyzerCheckersAndPackages(ClangTidyContext &Context, for (StringRef CheckName : RegisteredCheckers) { std::string ClangTidyCheckName((AnalyzerCheckNamePrefix + CheckName).str()); - if (CheckName.startswith("core") || + if (CheckName.starts_with("core") || Context.isCheckEnabled(ClangTidyCheckName)) { List.emplace_back(std::string(CheckName), true); } @@ -541,7 +541,7 @@ runClangTidy(clang::tidy::ClangTidyContext &Context, CommandLineArguments AdjustedArgs = Args; if (Opts.ExtraArgsBefore) { auto I = AdjustedArgs.begin(); - if (I != AdjustedArgs.end() && !StringRef(*I).startswith("-")) + if (I != AdjustedArgs.end() && !StringRef(*I).starts_with("-")) ++I; // Skip compiler binary name, if it is there. AdjustedArgs.insert(I, Opts.ExtraArgsBefore->begin(), Opts.ExtraArgsBefore->end()); diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index b19a84f5dc215776f95920a6fb84315e78b2d965..0a80c996aaaade5fdb7e523ea231354d0cbb0e2f 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -62,7 +62,7 @@ protected: // appending the check name to the message in ClangTidyContext::diag and // using getCustomDiagID. std::string CheckNameInMessage = " [" + Error.DiagnosticName + "]"; - if (Message.endswith(CheckNameInMessage)) + if (Message.ends_with(CheckNameInMessage)) Message = Message.substr(0, Message.size() - CheckNameInMessage.size()); auto TidyMessage = @@ -457,7 +457,7 @@ bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName, if (Context.getGlobalOptions().LineFilter.empty()) return true; for (const FileFilter &Filter : Context.getGlobalOptions().LineFilter) { - if (FileName.endswith(Filter.Name)) { + if (FileName.ends_with(Filter.Name)) { if (Filter.LineRanges.empty()) return true; for (const FileFilter::LineRange &Range : Filter.LineRanges) { diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp index 0b1e9f59e1a70c7c27edbd005f6747ceb441bea6..e414ac8c770508fed662084f39a6e469eb42edeb 100644 --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp @@ -23,10 +23,10 @@ public: /// Records that a given file entry is needed for replaying callbacks. void addNecessaryFile(FileEntryRef File) { // Don't record modulemap files because it breaks same file detection. - if (!(File.getName().endswith("module.modulemap") || - File.getName().endswith("module.private.modulemap") || - File.getName().endswith("module.map") || - File.getName().endswith("module_private.map"))) + if (!(File.getName().ends_with("module.modulemap") || + File.getName().ends_with("module.private.modulemap") || + File.getName().ends_with("module.map") || + File.getName().ends_with("module_private.map"))) FilesToRecord.insert(File); } diff --git a/clang-tools-extra/clang-tidy/GlobList.cpp b/clang-tools-extra/clang-tidy/GlobList.cpp index 4ff9d951110630f4417e3b69b8c4cd54ee06db03..694db35106fd6363b20ab5624cb920c4eda9c108 100644 --- a/clang-tools-extra/clang-tidy/GlobList.cpp +++ b/clang-tools-extra/clang-tidy/GlobList.cpp @@ -16,7 +16,7 @@ namespace clang::tidy { // from the GlobList. static bool consumeNegativeIndicator(StringRef &GlobList) { GlobList = GlobList.trim(); - if (GlobList.startswith("-")) { + if (GlobList.starts_with("-")) { GlobList = GlobList.substr(1); return true; } diff --git a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h index 1827f54a2bc064819fbfb6d1752af796621097d8..1eef86ddc00b955e0984cf23b2a371036578de77 100644 --- a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h +++ b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h @@ -52,7 +52,7 @@ AST_POLYMORPHIC_MATCHER( "profiling", "random", "status", "strings", "synchronization", "time", "types", "utility"}; return llvm::any_of(AbseilLibraries, [&](const char *Library) { - return Path.startswith(Library); + return Path.starts_with(Library); }); } diff --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp index 74ef6e67f00f34213c070253c2feba7869b7ff76..4a6f17ed5f86891088e24a71382e1745cba71f25 100644 --- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp @@ -27,7 +27,7 @@ std::optional makeCharacterLiteral(const StringLiteral *Literal, assert(Literal->getCharByteWidth() == 1 && "StrSplit doesn't support wide char"); std::string Result = clang::tooling::fixit::getText(*Literal, Context).str(); - bool IsRawStringLiteral = StringRef(Result).startswith(R"(R")"); + bool IsRawStringLiteral = StringRef(Result).starts_with(R"(R")"); // Since raw string literal might contain unescaped non-printable characters, // we normalize them using `StringLiteral::outputString`. if (IsRawStringLiteral) { diff --git a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp index 2a367d737742dca9756c0ab0a7545258a2c960bf..8cdd5d0a564675aa7264f72cdf8984b02ef8d41d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp @@ -185,7 +185,7 @@ static bool sameName(StringRef InComment, StringRef InDecl, bool StrictMode) { static bool looksLikeExpectMethod(const CXXMethodDecl *Expect) { return Expect != nullptr && Expect->getLocation().isMacroID() && Expect->getNameInfo().getName().isIdentifier() && - Expect->getName().startswith("gmock_"); + Expect->getName().starts_with("gmock_"); } static bool areMockAndExpectMethods(const CXXMethodDecl *Mock, const CXXMethodDecl *Expect) { diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 7a910037368c832b8e6df8e4c4fee0b18e64b7d5..435cb1e3fbcff34594bd4c90652ccc68c29790b7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -83,6 +83,7 @@ #include "UnhandledSelfAssignmentCheck.h" #include "UniquePtrArrayMismatchCheck.h" #include "UnsafeFunctionsCheck.h" +#include "UnusedLocalNonTrivialVariableCheck.h" #include "UnusedRaiiCheck.h" #include "UnusedReturnValueCheck.h" #include "UseAfterMoveCheck.h" @@ -235,6 +236,8 @@ public: "bugprone-unique-ptr-array-mismatch"); CheckFactories.registerCheck( "bugprone-unsafe-functions"); + CheckFactories.registerCheck( + "bugprone-unused-local-non-trivial-variable"); CheckFactories.registerCheck("bugprone-unused-raii"); CheckFactories.registerCheck( "bugprone-unused-return-value"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index d443fd8d1452f1685567d863b1348b826a62cbcc..70e7fbc7ec0c1448ac6004518d23a424fa398d3d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -79,6 +79,7 @@ add_clang_library(clangTidyBugproneModule UnhandledSelfAssignmentCheck.cpp UniquePtrArrayMismatchCheck.cpp UnsafeFunctionsCheck.cpp + UnusedLocalNonTrivialVariableCheck.cpp UnusedRaiiCheck.cpp UnusedReturnValueCheck.cpp UseAfterMoveCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp index 7b02576a6093cb0eae04b1f6a717d0ce17005258..84e99c7fafc74b2930bea63155fa3a1506152713 100644 --- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp @@ -1550,7 +1550,7 @@ static bool isIgnoredParameter(const TheCheck &Check, const ParmVarDecl *Node) { if (!NodeTypeName.empty()) { if (llvm::any_of(Check.IgnoredParameterTypeSuffixes, [NodeTypeName](StringRef E) { - return !E.empty() && NodeTypeName.endswith(E); + return !E.empty() && NodeTypeName.ends_with(E); })) { LLVM_DEBUG(llvm::dbgs() << "\tType suffix ignored.\n"); return true; diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp index 44db5029fd993629d43e11834668b30729b1ae05..977241e91b9a93b00a1572bbdd8e9df6c0581c67 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp @@ -385,7 +385,7 @@ static bool isDestExprFix(const MatchFinder::MatchResult &Result, std::string TempTyStr = Dest->getType().getAsString(); StringRef TyStr = TempTyStr; - if (TyStr.startswith("char") || TyStr.startswith("wchar_t")) + if (TyStr.starts_with("char") || TyStr.starts_with("wchar_t")) return false; Diag << FixItHint::CreateInsertion(Dest->getBeginLoc(), "(char *)"); @@ -721,8 +721,8 @@ void NotNullTerminatedResultCheck::registerMatchers(MatchFinder *Finder) { // Try to match with 'wchar_t' based function calls. std::string WcharHandlerFuncName = - "::" + (CC.Name.startswith("mem") ? "w" + CC.Name.str() - : "wcs" + CC.Name.substr(3).str()); + "::" + (CC.Name.starts_with("mem") ? "w" + CC.Name.str() + : "wcs" + CC.Name.substr(3).str()); return allOf(callee(functionDecl( hasAnyName(CharHandlerFuncName, WcharHandlerFuncName))), @@ -820,13 +820,13 @@ void NotNullTerminatedResultCheck::check( } StringRef Name = FunctionExpr->getDirectCallee()->getName(); - if (Name.startswith("mem") || Name.startswith("wmem")) + if (Name.starts_with("mem") || Name.starts_with("wmem")) memoryHandlerFunctionFix(Name, Result); else if (Name == "strerror_s") strerror_sFix(Result); - else if (Name.endswith("ncmp")) + else if (Name.ends_with("ncmp")) ncmpFix(Name, Result); - else if (Name.endswith("xfrm")) + else if (Name.ends_with("xfrm")) xfrmFix(Name, Result); } @@ -835,7 +835,7 @@ void NotNullTerminatedResultCheck::memoryHandlerFunctionFix( if (isCorrectGivenLength(Result)) return; - if (Name.endswith("chr")) { + if (Name.ends_with("chr")) { memchrFix(Name, Result); return; } @@ -849,13 +849,13 @@ void NotNullTerminatedResultCheck::memoryHandlerFunctionFix( "the result from calling '%0' is not null-terminated") << Name; - if (Name.endswith("cpy")) { + if (Name.ends_with("cpy")) { memcpyFix(Name, Result, Diag); - } else if (Name.endswith("cpy_s")) { + } else if (Name.ends_with("cpy_s")) { memcpy_sFix(Name, Result, Diag); - } else if (Name.endswith("move")) { + } else if (Name.ends_with("move")) { memmoveFix(Name, Result, Diag); - } else if (Name.endswith("move_s")) { + } else if (Name.ends_with("move_s")) { isDestCapacityFix(Result, Diag); lengthArgHandle(LengthHandleKind::Increase, Result, Diag); } diff --git a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp index 6eefde369c59e52ebd3810e26b9644002af9a153..7a06df454be99871dc170f2c0e412873d04e7a29 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp @@ -81,7 +81,7 @@ static bool hasReservedDoubleUnderscore(StringRef Name, const LangOptions &LangOpts) { if (LangOpts.CPlusPlus) return Name.contains("__"); - return Name.startswith("__"); + return Name.starts_with("__"); } static std::optional diff --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp index fd3ca76e68a61bc9d41bfed9541d07a3a2429be6..902490f4d33c13bd3eb1f7addae6995937d0089c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp @@ -282,7 +282,7 @@ bool isStandardFunction(const FunctionDecl *FD) { /// and every other statement that is declared in file ExprCXX.h. bool isCXXOnlyStmt(const Stmt *S) { StringRef Name = S->getStmtClassName(); - if (Name.startswith("CXX")) + if (Name.starts_with("CXX")) return true; // Check for all other class names in ExprCXX.h that have no 'CXX' prefix. return isagetASTContext()) || + Node.isTriviallyCopyableType(Finder->getASTContext()); +} +} // namespace + +UnusedLocalNonTrivialVariableCheck::UnusedLocalNonTrivialVariableCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IncludeTypes(utils::options::parseStringList( + Options.get("IncludeTypes", DefaultIncludeTypeRegex))), + ExcludeTypes( + utils::options::parseStringList(Options.get("ExcludeTypes", ""))) {} + +void UnusedLocalNonTrivialVariableCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeTypes", + utils::options::serializeStringList(IncludeTypes)); + Options.store(Opts, "ExcludeTypes", + utils::options::serializeStringList(ExcludeTypes)); +} + +void UnusedLocalNonTrivialVariableCheck::registerMatchers(MatchFinder *Finder) { + if (IncludeTypes.empty()) + return; + + Finder->addMatcher( + varDecl(isLocalVarDecl(), unless(isReferenced()), + unless(isExceptionVariable()), hasLocalStorage(), isDefinition(), + unless(hasType(isReferenceType())), unless(hasType(isTrivial())), + hasType(hasUnqualifiedDesugaredType( + anyOf(recordType(hasDeclaration(namedDecl( + matchesAnyListedName(IncludeTypes), + unless(matchesAnyListedName(ExcludeTypes))))), + templateSpecializationType(hasDeclaration(namedDecl( + matchesAnyListedName(IncludeTypes), + unless(matchesAnyListedName(ExcludeTypes))))))))) + .bind("var"), + this); +} + +void UnusedLocalNonTrivialVariableCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs("var"); + diag(MatchedDecl->getLocation(), "unused local variable %0 of type %1") + << MatchedDecl << MatchedDecl->getType(); +} + +bool UnusedLocalNonTrivialVariableCheck::isLanguageVersionSupported( + const LangOptions &LangOpts) const { + return LangOpts.CPlusPlus; +} + +std::optional +UnusedLocalNonTrivialVariableCheck::getCheckTraversalKind() const { + return TK_IgnoreUnlessSpelledInSource; +} + +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedLocalNonTrivialVariableCheck.h b/clang-tools-extra/clang-tidy/bugprone/UnusedLocalNonTrivialVariableCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..e79b803a2158b670cf4da4915cf3923cdf4e824c --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedLocalNonTrivialVariableCheck.h @@ -0,0 +1,44 @@ +//===--- UnusedLocalNonTrivialVariableCheck.h - clang-tidy ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDLOCALNONTRIVIALVARIABLECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDLOCALNONTRIVIALVARIABLECHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Warns when a local non trivial variable is unused within a function. By +/// default std::.*mutex and std::future are included. +/// +/// The check supports these options: +/// - 'IncludeTypes': a semicolon-separated list of regular expressions +/// matching types to ensure must be used. +/// - 'ExcludeTypes': a semicolon-separated list of regular expressions +/// matching types that are excluded from the +/// 'IncludeTypes' matches. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/unused-local-non-trivial-variable.html +class UnusedLocalNonTrivialVariableCheck : public ClangTidyCheck { +public: + UnusedLocalNonTrivialVariableCheck(StringRef Name, ClangTidyContext *Context); + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override; + std::optional getCheckTraversalKind() const override; + +private: + const std::vector IncludeTypes; + const std::vector ExcludeTypes; +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDLOCALNONTRIVIALVARIABLECHECK_H diff --git a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp index 714ac0ee54dafb35ac7d7c567a7ecf15b54b167d..995961b0774802e34c05095a8985594a158a9fb0 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp @@ -148,14 +148,15 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) { return; // Ignore code in .c files and headers included from them, even if they are // compiled as C++. - if (getCurrentMainFile().endswith(".c")) + if (getCurrentMainFile().ends_with(".c")) return; SourceManager &SM = *Result.SourceManager; // Ignore code in .c files #included in other files (which shouldn't be done, // but people still do this for test and other purposes). - if (SM.getFilename(SM.getSpellingLoc(CastExpr->getBeginLoc())).endswith(".c")) + if (SM.getFilename(SM.getSpellingLoc(CastExpr->getBeginLoc())) + .ends_with(".c")) return; // Leave type spelling exactly as it was (unlike diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp index ce57b9fc3cac10a5af6a7095d44487253f918978..805dcaf3ce4025274368993b004fdc48c322e69b 100644 --- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp @@ -66,7 +66,7 @@ public: // recent enough version of Google Test. llvm::StringRef FileName = PP->getSourceManager().getFilename( MD->getMacroInfo()->getDefinitionLoc()); - ReplacementFound = FileName.endswith("gtest/gtest-typed-test.h") && + ReplacementFound = FileName.ends_with("gtest/gtest-typed-test.h") && PP->getSpelling(MacroNameTok) == "TYPED_TEST_SUITE"; } } @@ -102,7 +102,7 @@ private: llvm::StringRef FileName = PP->getSourceManager().getFilename( MD.getMacroInfo()->getDefinitionLoc()); - if (!FileName.endswith("gtest/gtest-typed-test.h")) + if (!FileName.ends_with("gtest/gtest-typed-test.h")) return; DiagnosticBuilder Diag = Check->diag(Loc, RenameCaseToSuiteMessage); diff --git a/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp b/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp index 2f4913b2d435ac2bfa114399e94b66f6ccd83b66..c97bd48e6c3e3aff904db2d715255e1506fe465e 100644 --- a/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp @@ -40,7 +40,7 @@ void UsingNamespaceDirectiveCheck::check( bool UsingNamespaceDirectiveCheck::isStdLiteralsNamespace( const NamespaceDecl *NS) { - if (!NS->getName().endswith("literals")) + if (!NS->getName().ends_with("literals")) return false; const auto *Parent = dyn_cast_or_null(NS->getParent()); diff --git a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp index 8d35ff56de781dff19be30b9590cbe448ebe9431..42d358a15083ab038f6b9eed73d7a6c4d52fe7ac 100644 --- a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp @@ -54,11 +54,11 @@ std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename, std::replace(Guard.begin(), Guard.end(), '-', '_'); // The prevalent style in clang is LLVM_CLANG_FOO_BAR_H - if (StringRef(Guard).startswith("clang")) + if (StringRef(Guard).starts_with("clang")) Guard = "LLVM_" + Guard; // The prevalent style in flang is FORTRAN_FOO_BAR_H - if (StringRef(Guard).startswith("flang")) + if (StringRef(Guard).starts_with("flang")) Guard = "FORTRAN" + Guard.substr(sizeof("flang") - 1); return StringRef(Guard).upper(); diff --git a/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp b/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp index 3fb2e8daaebed9c9bb1dea517517eea1a8bd6d88..bdd72f85e2a27c66a611ddbf879b88cc230acd3b 100644 --- a/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp @@ -61,13 +61,13 @@ static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) { return 0; // LLVM and clang headers are in the penultimate position. - if (Filename.startswith("llvm/") || Filename.startswith("llvm-c/") || - Filename.startswith("clang/") || Filename.startswith("clang-c/")) + if (Filename.starts_with("llvm/") || Filename.starts_with("llvm-c/") || + Filename.starts_with("clang/") || Filename.starts_with("clang-c/")) return 2; // Put these between system and llvm headers to be consistent with LLVM // clang-format style. - if (Filename.startswith("gtest/") || Filename.startswith("gmock/")) + if (Filename.starts_with("gtest/") || Filename.starts_with("gmock/")) return 3; // System headers are sorted to the end. diff --git a/clang-tools-extra/clang-tidy/misc/ConfusableTable/BuildConfusableTable.cpp b/clang-tools-extra/clang-tidy/misc/ConfusableTable/BuildConfusableTable.cpp index 79ebb2387179ea4f5e433e1897616f793a01522f..e269ab3983f36cfe53e3806d95547d647aec2aa5 100644 --- a/clang-tools-extra/clang-tidy/misc/ConfusableTable/BuildConfusableTable.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConfusableTable/BuildConfusableTable.cpp @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) { std::vector>> Entries; SmallVector Values; for (StringRef Line : Lines) { - if (Line.startswith("#")) + if (Line.starts_with("#")) continue; Values.clear(); diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp index 5ae6caedb7f4c0368c755ae9d9dc89d1b6f8400a..5e7a0e65690b7aaa704cf5c033eb92c2a11127bc 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp @@ -180,7 +180,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) { // Since most private -> public mappings happen in a verbatim way, we // check textually here. This might go wrong in presence of symlinks or // header mappings. But that's not different than rest of the places. - if (getCurrentMainFile().endswith(PHeader)) + if (getCurrentMainFile().ends_with(PHeader)) continue; } auto StdHeader = tooling::stdlib::Header::named( diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp index fa8343220dd05a399a8358d80f81014793fefa69..6bb9a349d69b13f22d587cd4fa8120c4f8f6f2ae 100644 --- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp @@ -1285,7 +1285,7 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) { const auto Diag = diag(Op->getExprLoc(), Message); for (const auto &KeyValue : Result.Nodes.getMap()) { - if (StringRef(KeyValue.first).startswith("duplicate")) + if (StringRef(KeyValue.first).starts_with("duplicate")) Diag << KeyValue.second.getSourceRange(); } } diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp index e7e01bab0e9d5233c1a2ac1fa337833f938940a7..c0bf4903ec3911af762abf99f71d89947b09b732 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp @@ -849,14 +849,14 @@ std::string VariableNamer::createIndexName() { ContainerName = TheContainer->getName(); size_t Len = ContainerName.size(); - if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) { + if (Len > 1 && ContainerName.ends_with(Style == NS_UpperCase ? "S" : "s")) { IteratorName = std::string(ContainerName.substr(0, Len - 1)); // E.g.: (auto thing : things) if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) return IteratorName; } - if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) { + if (Len > 2 && ContainerName.ends_with(Style == NS_UpperCase ? "S_" : "s_")) { IteratorName = std::string(ContainerName.substr(0, Len - 2)); // E.g.: (auto thing : things_) if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp index f5d13f31d7a644ddc6e55936910ba2ecd9df4764..6a295dbfd05820cc1f5a14b804ca174280fc26f7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -83,7 +83,7 @@ void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) { StringRef ContainerText = Lexer::getSourceText( CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()), *Result.SourceManager, getLangOpts()); - if (ContainerText.startswith("std::")) + if (ContainerText.starts_with("std::")) NewName = "std::" + NewName; Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange()); diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index b85dde5644d313fcb6d4e7c3c97610a9fd2491b2..4438f0b22063f5c7650769bee9b25b3819147448 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -41,11 +41,11 @@ AST_MATCHER_P(NamedDecl, hasAnyNameIgnoringTemplates, std::vector, // FullNameTrimmed matches any of the given Names. const StringRef FullNameTrimmedRef = FullNameTrimmed; for (const StringRef Pattern : Names) { - if (Pattern.startswith("::")) { + if (Pattern.starts_with("::")) { if (FullNameTrimmed == Pattern) return true; - } else if (FullNameTrimmedRef.endswith(Pattern) && - FullNameTrimmedRef.drop_back(Pattern.size()).endswith("::")) { + } else if (FullNameTrimmedRef.ends_with(Pattern) && + FullNameTrimmedRef.drop_back(Pattern.size()).ends_with("::")) { return true; } } diff --git a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp index 299d4539a6ddcb01045f671b3e82891d0a2611af..6de80dcb99c60d374cc1362675f9a64c45ccd270 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp @@ -20,7 +20,7 @@ static bool doesNoDiscardMacroExist(ASTContext &Context, const llvm::StringRef &MacroId) { // Don't check for the Macro existence if we are using an attribute // either a C++17 standard attribute or pre C++17 syntax - if (MacroId.startswith("[[") || MacroId.startswith("__attribute__")) + if (MacroId.starts_with("[[") || MacroId.starts_with("__attribute__")) return true; // Otherwise look up the macro name in the context to see if its defined. diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index e6293ed48bfddbbcb59fa12af2a56803b3fbac00..bb05f206c717cea3a4c2067e7473d4a30dccdc12 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -11,26 +11,39 @@ #include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; +namespace { + +AST_MATCHER(clang::LinkageSpecDecl, isExternCLinkage) { + return Node.getLanguage() == clang::LinkageSpecLanguageIDs::C; +} +} // namespace namespace clang::tidy::modernize { +static constexpr llvm::StringLiteral ExternCDeclName = "extern-c-decl"; static constexpr llvm::StringLiteral ParentDeclName = "parent-decl"; static constexpr llvm::StringLiteral TagDeclName = "tag-decl"; static constexpr llvm::StringLiteral TypedefName = "typedef"; UseUsingCheck::UseUsingCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} + IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)), + IgnoreExternC(Options.get("IgnoreExternC", false)) {} void UseUsingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreMacros", IgnoreMacros); + Options.store(Opts, "IgnoreExternC", IgnoreExternC); } void UseUsingCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(typedefDecl(unless(isInstantiated()), - hasParent(decl().bind(ParentDeclName))) - .bind(TypedefName), - this); + Finder->addMatcher( + typedefDecl( + unless(isInstantiated()), + optionally(hasAncestor( + linkageSpecDecl(isExternCLinkage()).bind(ExternCDeclName))), + hasParent(decl().bind(ParentDeclName))) + .bind(TypedefName), + this); // This matcher is used to find tag declarations in source code within // typedefs. They appear in the AST just *prior* to the typedefs. @@ -70,6 +83,11 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { if (MatchedDecl->getLocation().isInvalid()) return; + const auto *ExternCDecl = + Result.Nodes.getNodeAs(ExternCDeclName); + if (ExternCDecl && IgnoreExternC) + return; + SourceLocation StartLoc = MatchedDecl->getBeginLoc(); if (StartLoc.isMacroID() && IgnoreMacros) @@ -122,7 +140,8 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { Type = FirstTypedefName + Type.substr(FirstTypedefType.size() + 1); } if (!ReplaceRange.getEnd().isMacroID()) { - const SourceLocation::IntTy Offset = MatchedDecl->getFunctionType() ? 0 : Name.size(); + const SourceLocation::IntTy Offset = + MatchedDecl->getFunctionType() ? 0 : Name.size(); LastReplacementEnd = ReplaceRange.getEnd().getLocWithOffset(Offset); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h index 5c741a92d013100d90561327871bb68901328d9e..7054778d84a0c66640ea67f5d8981057d6a5c7fd 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h @@ -20,6 +20,7 @@ namespace clang::tidy::modernize { class UseUsingCheck : public ClangTidyCheck { const bool IgnoreMacros; + const bool IgnoreExternC; SourceLocation LastReplacementEnd; llvm::DenseMap LastTagDeclRanges; diff --git a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp index 3c8751dbdd733f8036709541ce38b882881a4d1b..ad900fcec2dee1d45743261e4da98e140924dc8a 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp @@ -97,7 +97,7 @@ void InefficientAlgorithmCheck::check(const MatchFinder::MatchResult &Result) { if (!AlgDecl) return; - if (Unordered && AlgDecl->getName().find("bound") != llvm::StringRef::npos) + if (Unordered && AlgDecl->getName().contains("bound")) return; const auto *AlgParam = Result.Nodes.getNodeAs("AlgParam"); diff --git a/clang-tools-extra/clang-tidy/plugin/ClangTidyPlugin.cpp b/clang-tools-extra/clang-tidy/plugin/ClangTidyPlugin.cpp index b47ce2b066c65298ccd98afc8779bee6a87b9b43..7911583db30e450bbadc2225c521396ef7849204 100644 --- a/clang-tools-extra/clang-tidy/plugin/ClangTidyPlugin.cpp +++ b/clang-tools-extra/clang-tidy/plugin/ClangTidyPlugin.cpp @@ -62,7 +62,7 @@ public: // Parse the extra command line args. // FIXME: This is very limited at the moment. for (StringRef Arg : Args) - if (Arg.startswith("-checks=")) + if (Arg.starts_with("-checks=")) OverrideOptions.Checks = std::string(Arg.substr(strlen("-checks="))); auto Options = std::make_unique( diff --git a/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp b/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp index 4a3e43bda9172f44a812df0a767e4d89e7f585de..3e77a204d753eb2e3906ef2e93833fd2fbcdcab7 100644 --- a/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp @@ -59,17 +59,17 @@ static StringRef trySuggestX86(StringRef Name) { return {}; // [simd.alg] - if (Name.startswith("max_")) + if (Name.starts_with("max_")) return "$simd::max"; - if (Name.startswith("min_")) + if (Name.starts_with("min_")) return "$simd::min"; // [simd.binary] - if (Name.startswith("add_")) + if (Name.starts_with("add_")) return "operator+ on $simd objects"; - if (Name.startswith("sub_")) + if (Name.starts_with("sub_")) return "operator- on $simd objects"; - if (Name.startswith("mul_")) + if (Name.starts_with("mul_")) return "operator* on $simd objects"; return {}; diff --git a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp index d8dbaa7c9d73c419f5641a4dc3f02549a7f82b72..81ca33cbbdfb4b5461b54b8a0b5903c0d1186942 100644 --- a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp @@ -79,7 +79,7 @@ static SourceLocation findEndLocation(const Stmt &S, const SourceManager &SM, SourceRange TokRange(Loc, TokEndLoc); StringRef Comment = Lexer::getSourceText( CharSourceRange::getTokenRange(TokRange), SM, Context->getLangOpts()); - if (Comment.startswith("/*") && Comment.contains('\n')) { + if (Comment.starts_with("/*") && Comment.contains('\n')) { // Multi-line block comment, insert brace before. break; } diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 18c5e144e46fe77a00e06752b008a09d4bee5e34..e6f44dd51b459631bce86c5bb8a559565689eeeb 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -9,6 +9,7 @@ #include "IdentifierNamingCheck.h" #include "../GlobList.h" +#include "../utils/ASTUtils.h" #include "clang/AST/CXXInheritance.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" @@ -286,7 +287,9 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions( HPTOpt.value_or(IdentifierNamingCheck::HPT_Off)); } bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false); - return {std::move(Styles), std::move(HNOption), IgnoreMainLike}; + bool CheckAnonFieldInParent = Options.get("CheckAnonFieldInParent", false); + return {std::move(Styles), std::move(HNOption), IgnoreMainLike, + CheckAnonFieldInParent}; } std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( @@ -859,6 +862,8 @@ void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit); Options.store(Opts, "IgnoreMainLikeFunctions", MainFileStyle->isIgnoringMainLikeFunction()); + Options.store(Opts, "CheckAnonFieldInParent", + MainFileStyle->isCheckingAnonFieldInParentScope()); } bool IdentifierNamingCheck::matchesStyle( @@ -889,7 +894,7 @@ bool IdentifierNamingCheck::matchesStyle( // Ensure the name doesn't have any extra underscores beyond those specified // in the prefix and suffix. - if (Name.startswith("_") || Name.endswith("_")) + if (Name.starts_with("_") || Name.ends_with("_")) return false; if (Style.Case && !Matchers[static_cast(*Style.Case)].match(Name)) @@ -1111,7 +1116,7 @@ std::string IdentifierNamingCheck::fixupWithStyle( StyleKind IdentifierNamingCheck::findStyleKind( const NamedDecl *D, ArrayRef> NamingStyles, - bool IgnoreMainLikeFunctions) const { + bool IgnoreMainLikeFunctions, bool CheckAnonFieldInParentScope) const { assert(D && D->getIdentifier() && !D->getName().empty() && !D->isImplicit() && "Decl must be an explicit identifier with a name."); @@ -1185,29 +1190,14 @@ StyleKind IdentifierNamingCheck::findStyleKind( } if (const auto *Decl = dyn_cast(D)) { - QualType Type = Decl->getType(); - - if (!Type.isNull() && Type.isConstQualified()) { - if (NamingStyles[SK_ConstantMember]) - return SK_ConstantMember; - - if (NamingStyles[SK_Constant]) - return SK_Constant; + if (CheckAnonFieldInParentScope) { + const RecordDecl *Record = Decl->getParent(); + if (Record->isAnonymousStructOrUnion()) { + return findStyleKindForAnonField(Decl, NamingStyles); + } } - if (Decl->getAccess() == AS_private && NamingStyles[SK_PrivateMember]) - return SK_PrivateMember; - - if (Decl->getAccess() == AS_protected && NamingStyles[SK_ProtectedMember]) - return SK_ProtectedMember; - - if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMember]) - return SK_PublicMember; - - if (NamingStyles[SK_Member]) - return SK_Member; - - return SK_Invalid; + return findStyleKindForField(Decl, Decl->getType(), NamingStyles); } if (const auto *Decl = dyn_cast(D)) { @@ -1244,66 +1234,7 @@ StyleKind IdentifierNamingCheck::findStyleKind( } if (const auto *Decl = dyn_cast(D)) { - QualType Type = Decl->getType(); - - if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable]) - return SK_ConstexprVariable; - - if (!Type.isNull() && Type.isConstQualified()) { - if (Decl->isStaticDataMember() && NamingStyles[SK_ClassConstant]) - return SK_ClassConstant; - - if (Decl->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && - NamingStyles[SK_GlobalConstantPointer]) - return SK_GlobalConstantPointer; - - if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalConstant]) - return SK_GlobalConstant; - - if (Decl->isStaticLocal() && NamingStyles[SK_StaticConstant]) - return SK_StaticConstant; - - if (Decl->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && - NamingStyles[SK_LocalConstantPointer]) - return SK_LocalConstantPointer; - - if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalConstant]) - return SK_LocalConstant; - - if (Decl->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalConstant]) - return SK_LocalConstant; - - if (NamingStyles[SK_Constant]) - return SK_Constant; - } - - if (Decl->isStaticDataMember() && NamingStyles[SK_ClassMember]) - return SK_ClassMember; - - if (Decl->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && - NamingStyles[SK_GlobalPointer]) - return SK_GlobalPointer; - - if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalVariable]) - return SK_GlobalVariable; - - if (Decl->isStaticLocal() && NamingStyles[SK_StaticVariable]) - return SK_StaticVariable; - - if (Decl->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && - NamingStyles[SK_LocalPointer]) - return SK_LocalPointer; - - if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalVariable]) - return SK_LocalVariable; - - if (Decl->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalVariable]) - return SK_LocalVariable; - - if (NamingStyles[SK_Variable]) - return SK_Variable; - - return SK_Invalid; + return findStyleKindForVar(Decl, Decl->getType(), NamingStyles); } if (const auto *Decl = dyn_cast(D)) { @@ -1442,12 +1373,13 @@ IdentifierNamingCheck::getDeclFailureInfo(const NamedDecl *Decl, if (!FileStyle.isActive()) return std::nullopt; - return getFailureInfo(HungarianNotation.getDeclTypeName(Decl), - Decl->getName(), Decl, Loc, FileStyle.getStyles(), - FileStyle.getHNOption(), - findStyleKind(Decl, FileStyle.getStyles(), - FileStyle.isIgnoringMainLikeFunction()), - SM, IgnoreFailedSplit); + return getFailureInfo( + HungarianNotation.getDeclTypeName(Decl), Decl->getName(), Decl, Loc, + FileStyle.getStyles(), FileStyle.getHNOption(), + findStyleKind(Decl, FileStyle.getStyles(), + FileStyle.isIgnoringMainLikeFunction(), + FileStyle.isCheckingAnonFieldInParentScope()), + SM, IgnoreFailedSplit); } std::optional @@ -1496,5 +1428,114 @@ IdentifierNamingCheck::getStyleForFile(StringRef FileName) const { return It.first->getValue(); } +StyleKind IdentifierNamingCheck::findStyleKindForAnonField( + const FieldDecl *AnonField, + ArrayRef> NamingStyles) const { + const IndirectFieldDecl *IFD = + utils::findOutermostIndirectFieldDeclForField(AnonField); + assert(IFD && "Found an anonymous record field without an IndirectFieldDecl"); + + QualType Type = AnonField->getType(); + + if (const auto *F = dyn_cast(IFD->chain().front())) { + return findStyleKindForField(F, Type, NamingStyles); + } + + if (const auto *V = IFD->getVarDecl()) { + return findStyleKindForVar(V, Type, NamingStyles); + } + + return SK_Invalid; +} + +StyleKind IdentifierNamingCheck::findStyleKindForField( + const FieldDecl *Field, QualType Type, + ArrayRef> NamingStyles) const { + if (!Type.isNull() && Type.isConstQualified()) { + if (NamingStyles[SK_ConstantMember]) + return SK_ConstantMember; + + if (NamingStyles[SK_Constant]) + return SK_Constant; + } + + if (Field->getAccess() == AS_private && NamingStyles[SK_PrivateMember]) + return SK_PrivateMember; + + if (Field->getAccess() == AS_protected && NamingStyles[SK_ProtectedMember]) + return SK_ProtectedMember; + + if (Field->getAccess() == AS_public && NamingStyles[SK_PublicMember]) + return SK_PublicMember; + + if (NamingStyles[SK_Member]) + return SK_Member; + + return SK_Invalid; +} + +StyleKind IdentifierNamingCheck::findStyleKindForVar( + const VarDecl *Var, QualType Type, + ArrayRef> NamingStyles) const { + if (Var->isConstexpr() && NamingStyles[SK_ConstexprVariable]) + return SK_ConstexprVariable; + + if (!Type.isNull() && Type.isConstQualified()) { + if (Var->isStaticDataMember() && NamingStyles[SK_ClassConstant]) + return SK_ClassConstant; + + if (Var->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && + NamingStyles[SK_GlobalConstantPointer]) + return SK_GlobalConstantPointer; + + if (Var->isFileVarDecl() && NamingStyles[SK_GlobalConstant]) + return SK_GlobalConstant; + + if (Var->isStaticLocal() && NamingStyles[SK_StaticConstant]) + return SK_StaticConstant; + + if (Var->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && + NamingStyles[SK_LocalConstantPointer]) + return SK_LocalConstantPointer; + + if (Var->isLocalVarDecl() && NamingStyles[SK_LocalConstant]) + return SK_LocalConstant; + + if (Var->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalConstant]) + return SK_LocalConstant; + + if (NamingStyles[SK_Constant]) + return SK_Constant; + } + + if (Var->isStaticDataMember() && NamingStyles[SK_ClassMember]) + return SK_ClassMember; + + if (Var->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && + NamingStyles[SK_GlobalPointer]) + return SK_GlobalPointer; + + if (Var->isFileVarDecl() && NamingStyles[SK_GlobalVariable]) + return SK_GlobalVariable; + + if (Var->isStaticLocal() && NamingStyles[SK_StaticVariable]) + return SK_StaticVariable; + + if (Var->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && + NamingStyles[SK_LocalPointer]) + return SK_LocalPointer; + + if (Var->isLocalVarDecl() && NamingStyles[SK_LocalVariable]) + return SK_LocalVariable; + + if (Var->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalVariable]) + return SK_LocalVariable; + + if (NamingStyles[SK_Variable]) + return SK_Variable; + + return SK_Invalid; +} + } // namespace readability } // namespace clang::tidy diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h index 14626981cc42d8f060340d0a27388448593df0f0..27c8e4bc768c40637147bff4d96ec4c1d44bf38c 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h @@ -127,9 +127,11 @@ public: struct FileStyle { FileStyle() : IsActive(false), IgnoreMainLikeFunctions(false) {} FileStyle(SmallVectorImpl> &&Styles, - HungarianNotationOption HNOption, bool IgnoreMainLike) + HungarianNotationOption HNOption, bool IgnoreMainLike, + bool CheckAnonFieldInParent) : Styles(std::move(Styles)), HNOption(std::move(HNOption)), - IsActive(true), IgnoreMainLikeFunctions(IgnoreMainLike) {} + IsActive(true), IgnoreMainLikeFunctions(IgnoreMainLike), + CheckAnonFieldInParentScope(CheckAnonFieldInParent) {} ArrayRef> getStyles() const { assert(IsActive); @@ -144,11 +146,16 @@ public: bool isActive() const { return IsActive; } bool isIgnoringMainLikeFunction() const { return IgnoreMainLikeFunctions; } + bool isCheckingAnonFieldInParentScope() const { + return CheckAnonFieldInParentScope; + } + private: SmallVector, 0> Styles; HungarianNotationOption HNOption; bool IsActive; bool IgnoreMainLikeFunctions; + bool CheckAnonFieldInParentScope; }; IdentifierNamingCheck::FileStyle @@ -175,7 +182,7 @@ public: StyleKind findStyleKind( const NamedDecl *D, ArrayRef> NamingStyles, - bool IgnoreMainLikeFunctions) const; + bool IgnoreMainLikeFunctions, bool CheckAnonFieldInParentScope) const; std::optional getFailureInfo( StringRef Type, StringRef Name, const NamedDecl *ND, @@ -199,6 +206,19 @@ private: const FileStyle &getStyleForFile(StringRef FileName) const; + /// Find the style kind of a field in an anonymous record. + StyleKind findStyleKindForAnonField( + const FieldDecl *AnonField, + ArrayRef> NamingStyles) const; + + StyleKind findStyleKindForField( + const FieldDecl *Field, QualType Type, + ArrayRef> NamingStyles) const; + + StyleKind + findStyleKindForVar(const VarDecl *Var, QualType Type, + ArrayRef> NamingStyles) const; + /// Stores the style options as a vector, indexed by the specified \ref /// StyleKind, for a given directory. mutable llvm::StringMap NamingStylesCache; diff --git a/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp index 9140b1f51631bb3fe26a7c66bcb14da19d39aca7..ca6503753f6b45a32ae4b9fa8f95124ead2e22e9 100644 --- a/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp @@ -235,7 +235,7 @@ createIsolatedDecls(llvm::ArrayRef Snippets) { for (std::size_t I = 1; I < Snippets.size(); ++I) Decls[I - 1] = Twine(Snippets[0]) - .concat(Snippets[0].endswith(" ") ? "" : " ") + .concat(Snippets[0].ends_with(" ") ? "" : " ") .concat(Snippets[I].ltrim()) .concat(";") .str(); diff --git a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp index 2c011f5c0e690485eee5fda1a521b996396be01c..e32f79589a059bd88d113aeb261723e2ce9feca1 100644 --- a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "MisleadingIndentationCheck.h" +#include "../utils/LexerUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -51,8 +52,20 @@ void MisleadingIndentationCheck::danglingElseCheck(const SourceManager &SM, diag(ElseLoc, "different indentation for 'if' and corresponding 'else'"); } -void MisleadingIndentationCheck::missingBracesCheck(const SourceManager &SM, - const CompoundStmt *CStmt) { +static bool isAtStartOfLineIncludingEmptyMacro(SourceLocation NextLoc, + const SourceManager &SM, + const LangOptions &LangOpts) { + const SourceLocation BeforeLoc = + utils::lexer::getPreviousTokenAndStart(NextLoc, SM, LangOpts).second; + if (BeforeLoc.isInvalid()) + return false; + return SM.getExpansionLineNumber(BeforeLoc) != + SM.getExpansionLineNumber(NextLoc); +} + +void MisleadingIndentationCheck::missingBracesCheck( + const SourceManager &SM, const CompoundStmt *CStmt, + const LangOptions &LangOpts) { const static StringRef StmtNames[] = {"if", "for", "while"}; for (unsigned int I = 0; I < CStmt->size() - 1; I++) { const Stmt *CurrentStmt = CStmt->body_begin()[I]; @@ -92,6 +105,8 @@ void MisleadingIndentationCheck::missingBracesCheck(const SourceManager &SM, if (NextLoc.isInvalid() || NextLoc.isMacroID()) continue; + if (!isAtStartOfLineIncludingEmptyMacro(NextLoc, SM, LangOpts)) + continue; if (SM.getExpansionColumnNumber(InnerLoc) == SM.getExpansionColumnNumber(NextLoc)) { @@ -117,7 +132,8 @@ void MisleadingIndentationCheck::check(const MatchFinder::MatchResult &Result) { danglingElseCheck(*Result.SourceManager, Result.Context, If); if (const auto *CStmt = Result.Nodes.getNodeAs("compound")) - missingBracesCheck(*Result.SourceManager, CStmt); + missingBracesCheck(*Result.SourceManager, CStmt, + Result.Context->getLangOpts()); } } // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h index c336abbc7c4a9199874dd9eda584f16fdf7eaf59..9c92fc1e18b6f3a1a097763ed44626b194079ebc 100644 --- a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h +++ b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.h @@ -32,7 +32,8 @@ public: private: void danglingElseCheck(const SourceManager &SM, ASTContext *Context, const IfStmt *If); - void missingBracesCheck(const SourceManager &SM, const CompoundStmt *CStmt); + void missingBracesCheck(const SourceManager &SM, const CompoundStmt *CStmt, + const LangOptions &LangOpts); }; } // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp index 68e9dd4998473b5bb4ec928685350e627a33c911..120ec02e9ad7dc8caa7544e5757f1068fea1a4ab 100644 --- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp @@ -160,7 +160,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { } // Otherwise we need to fix the comment. - NeedLineBreak = Comment.startswith("/*"); + NeedLineBreak = Comment.starts_with("/*"); OldCommentRange = SourceRange(AfterRBrace, Loc.getLocWithOffset(Tok.getLength())); Message = @@ -168,7 +168,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { "%0 ends with a comment that refers to a wrong namespace '") + NamespaceNameInComment + "'") .str(); - } else if (Comment.startswith("//")) { + } else if (Comment.starts_with("//")) { // Assume that this is an unrecognized form of a namespace closing line // comment. Replace it. NeedLineBreak = false; diff --git a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp index d274abcbfabe8a6123fb994df378c830b4bb28ac..7d4698d27ed1602a374cd159a615ecf4106645f4 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp @@ -16,7 +16,8 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { static const char KDefaultTypes[] = - "::std::basic_string;::std::basic_string_view;::std::vector;::std::array"; + "::std::basic_string;::std::basic_string_view;::std::vector;::std::array;::" + "std::span"; SimplifySubscriptExprCheck::SimplifySubscriptExprCheck( StringRef Name, ClangTidyContext *Context) diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp index 93c31d80c11381efeb6f8b6b42a9265afa825fc5..65356cc3929c54e7a28d2c63e2244d60a53d4dc3 100644 --- a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp @@ -85,7 +85,7 @@ void StaticAccessedThroughInstanceCheck::check( return; // Do not warn for CUDA built-in variables. - if (StringRef(BaseTypeName).startswith("__cuda_builtin_")) + if (StringRef(BaseTypeName).starts_with("__cuda_builtin_")) return; SourceLocation MemberExprStartLoc = MemberExpression->getBeginLoc(); diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index 0d2593e74f052b9a3259d40f7e85387ec6524dcc..9f3d6b6db6cbca1b0cc9aa3b7c71b4746f34d712 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -462,7 +462,7 @@ static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, if (Cur.empty()) continue; Cur.consume_front("-"); - if (Cur.startswith("clang-diagnostic")) + if (Cur.starts_with("clang-diagnostic")) continue; if (Cur.contains('*')) { SmallString<128> RegexText("^"); diff --git a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py index 8817e2914f6e25b82b6275a6dc3f5bfc03ec688a..d96b3450fdbe810db853dea0da09eac18682c4c0 100755 --- a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py +++ b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py @@ -173,6 +173,12 @@ def main(): help="checks filter, when not specified, use clang-tidy " "default", default="", ) + parser.add_argument( + "-config-file", + dest="config_file", + help="Specify the path of .clang-tidy or custom config file", + default="", + ) parser.add_argument("-use-color", action="store_true", help="Use colors in output") parser.add_argument( "-path", dest="build_path", help="Path used to read a compile command database." @@ -313,6 +319,8 @@ def main(): common_clang_tidy_args.append("-fix") if args.checks != "": common_clang_tidy_args.append("-checks=" + args.checks) + if args.config_file != "": + common_clang_tidy_args.append("-config-file=" + args.config_file) if args.quiet: common_clang_tidy_args.append("-quiet") if args.build_path is not None: diff --git a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp index 64333f2c187454e3c7d166e854964a5d12227213..fd5dadc9b01db13a8d7462f5573e03011bcf87a4 100644 --- a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp @@ -113,4 +113,28 @@ bool areStatementsIdentical(const Stmt *FirstStmt, const Stmt *SecondStmt, return DataFirst == DataSecond; } +const IndirectFieldDecl * +findOutermostIndirectFieldDeclForField(const FieldDecl *FD) { + const RecordDecl *Record = FD->getParent(); + assert(Record->isAnonymousStructOrUnion() && + "FD must be a field in an anonymous record"); + + const DeclContext *Context = Record; + while (isa(Context) && + cast(Context)->isAnonymousStructOrUnion()) { + Context = Context->getParent(); + } + + // Search for the target IndirectFieldDecl within the located context. + for (const auto *D : Context->decls()) { + const auto *IFD = dyn_cast(D); + if (!IFD) + continue; + if (IFD->getAnonField() == FD) + return IFD; + } + + return nullptr; +} + } // namespace clang::tidy::utils diff --git a/clang-tools-extra/clang-tidy/utils/ASTUtils.h b/clang-tools-extra/clang-tidy/utils/ASTUtils.h index 1bba5daf2fc765ab3d6ffbe5d0e01ef361df46af..6c3e54facd0202a233ba83e6c0ac7a2b26128cce 100644 --- a/clang-tools-extra/clang-tidy/utils/ASTUtils.h +++ b/clang-tools-extra/clang-tidy/utils/ASTUtils.h @@ -40,6 +40,11 @@ bool rangeCanBeFixed(SourceRange Range, const SourceManager *SM); bool areStatementsIdentical(const Stmt *FirstStmt, const Stmt *SecondStmt, const ASTContext &Context, bool Canonical = false); +// Given a field of an anonymous record, find its corresponding +// IndirectFieldDecl in the outermost possible scope. +const IndirectFieldDecl * +findOutermostIndirectFieldDeclForField(const FieldDecl *FD); + } // namespace clang::tidy::utils #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ASTUTILS_H diff --git a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp index eb21827bdeba3ccca719501e27361bd3a0ea7636..b6d9c50d0b109c1c24323e304500165a607287d3 100644 --- a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp +++ b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp @@ -19,7 +19,7 @@ namespace { StringRef removeFirstSuffix(StringRef Str, ArrayRef Suffixes) { for (StringRef Suffix : Suffixes) { - if (Str.endswith(Suffix)) { + if (Str.ends_with(Suffix)) { return Str.substr(0, Str.size() - Suffix.size()); } } @@ -73,12 +73,12 @@ determineIncludeKind(StringRef CanonicalFile, StringRef IncludeFile, if (IsAngled) { // If the system include () ends with ".h", then it is a normal C-style // include. Otherwise assume it is a C++-style extensionless include. - return IncludeFile.endswith(".h") ? IncludeSorter::IK_CSystemInclude - : IncludeSorter::IK_CXXSystemInclude; + return IncludeFile.ends_with(".h") ? IncludeSorter::IK_CSystemInclude + : IncludeSorter::IK_CXXSystemInclude; } StringRef CanonicalInclude = makeCanonicalName(IncludeFile, Style); - if (CanonicalFile.endswith(CanonicalInclude) - || CanonicalInclude.endswith(CanonicalFile)) { + if (CanonicalFile.ends_with(CanonicalInclude) || + CanonicalInclude.ends_with(CanonicalFile)) { return IncludeSorter::IK_MainTUInclude; } if ((Style == IncludeSorter::IS_Google) || @@ -95,8 +95,9 @@ determineIncludeKind(StringRef CanonicalFile, StringRef IncludeFile, } } if (Style == IncludeSorter::IS_Google_ObjC) { - if (IncludeFile.endswith(".generated.h") || - IncludeFile.endswith(".proto.h") || IncludeFile.endswith(".pbobjc.h")) { + if (IncludeFile.ends_with(".generated.h") || + IncludeFile.ends_with(".proto.h") || + IncludeFile.ends_with(".pbobjc.h")) { return IncludeSorter::IK_GeneratedInclude; } } diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h b/clang-tools-extra/clang-tidy/utils/Matchers.h index 386ea738fbba5088ba5ec57e988f4e4acf48139c..045e3ffbb6a8b45e0b24f877501fbc2d05493465 100644 --- a/clang-tools-extra/clang-tidy/utils/Matchers.h +++ b/clang-tools-extra/clang-tidy/utils/Matchers.h @@ -120,7 +120,7 @@ private: private: MatchMode determineMatchMode(llvm::StringRef Regex) { - if (Regex.startswith(":") || Regex.startswith("^:")) { + if (Regex.starts_with(":") || Regex.starts_with("^:")) { return MatchMode::MatchFullyQualified; } return Regex.contains(":") ? MatchMode::MatchQualified diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp index 5b81ec213ff9844688d6b2db86b774ab5b60b3c5..ae79eb21de9470fa3a82aa24c0b147a9625b34b5 100644 --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -193,7 +193,7 @@ std::string printQualifiedName(const NamedDecl &ND) { Policy.AnonymousTagLocations = false; ND.printQualifiedName(OS, Policy); OS.flush(); - assert(!StringRef(QName).startswith("::")); + assert(!StringRef(QName).starts_with("::")); return QName; } @@ -696,7 +696,7 @@ std::string getQualification(ASTContext &Context, const NamedDecl *ND, llvm::ArrayRef VisibleNamespaces) { for (llvm::StringRef NS : VisibleNamespaces) { - assert(NS.endswith("::")); + assert(NS.ends_with("::")); (void)NS; } return getQualification( diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 13d788162817fb4c1833831eb634a4a988afec03..6fb2641e8793db183bd1e7f4714eb31d6c2bf32c 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -437,7 +437,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos, ParseInputs ParseInput{IP->Command, &getHeaderFS(), IP->Contents.str()}; // FIXME: Add traling new line if there is none at eof, workaround a crash, // see https://github.com/clangd/clangd/issues/332 - if (!IP->Contents.endswith("\n")) + if (!IP->Contents.ends_with("\n")) ParseInput.Contents.append("\n"); ParseInput.Index = Index; @@ -488,7 +488,7 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos, ParseInputs ParseInput{IP->Command, &getHeaderFS(), IP->Contents.str()}; // FIXME: Add traling new line if there is none at eof, workaround a crash, // see https://github.com/clangd/clangd/issues/332 - if (!IP->Contents.endswith("\n")) + if (!IP->Contents.ends_with("\n")) ParseInput.Contents.append("\n"); ParseInput.Index = Index; CB(clangd::signatureHelp(File, Pos, *PreambleData, ParseInput, @@ -661,7 +661,7 @@ void ClangdServer::codeAction(const CodeActionInputs &Params, return true; return llvm::any_of(Only, [&](llvm::StringRef Base) { return Kind.consume_front(Base) && - (Kind.empty() || Kind.startswith(".")); + (Kind.empty() || Kind.starts_with(".")); }); }; diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 5eef43e93cb519f9944c9fff0432f8ca7b1f8792..0e5f08cec440cefc0a7169ba00d66c88726d0ab6 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -610,7 +610,7 @@ private: // foo<${1:class}>(${2:int p1}). // We transform this pattern to '<$1>()$0' or '<$0>()'. - bool EmptyArgs = llvm::StringRef(*Snippet).endswith("()"); + bool EmptyArgs = llvm::StringRef(*Snippet).ends_with("()"); if (Snippet->front() == '<') return EmptyArgs ? "<$1>()$0" : "<$1>($0)"; if (Snippet->front() == '(') @@ -625,7 +625,7 @@ private: // Classes and template using aliases can only have template arguments, // e.g. Foo<${1:class}>. - if (llvm::StringRef(*Snippet).endswith("<>")) + if (llvm::StringRef(*Snippet).ends_with("<>")) return "<>"; // can happen with defaulted template arguments. return "<$0>"; } @@ -1748,7 +1748,7 @@ public: S.append("::"); // visibleNamespaces doesn't include trailing ::. if (HeuristicPrefix.Qualifier.empty()) AllScopes = Opts.AllScopes; - else if (HeuristicPrefix.Qualifier.startswith("::")) { + else if (HeuristicPrefix.Qualifier.starts_with("::")) { Scopes.QueryScopes = {""}; Scopes.UnresolvedQualifier = std::string(HeuristicPrefix.Qualifier.drop_front(2)); @@ -2130,7 +2130,7 @@ CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, Result.Name = Content.slice(Rest.size(), Offset); // Consume qualifiers. - while (Rest.consume_back("::") && !Rest.endswith(":")) // reject :::: + while (Rest.consume_back("::") && !Rest.ends_with(":")) // reject :::: while (!Rest.empty() && isAsciiIdentifierContinue(Rest.back())) Rest = Rest.drop_back(); Result.Qualifier = @@ -2175,7 +2175,7 @@ CodeCompleteResult codeCompleteComment(PathRef FileName, unsigned Offset, Result.CompletionRange = CompletionRange; Result.Context = CodeCompletionContext::CCC_NaturalLanguage; for (llvm::StringRef Name : ParamNames) { - if (!Name.startswith(Prefix)) + if (!Name.starts_with(Prefix)) continue; CodeCompletion Item; Item.Name = Name.str() + "=*/"; @@ -2197,7 +2197,7 @@ maybeFunctionArgumentCommentStart(llvm::StringRef Content) { while (!Content.empty() && isAsciiIdentifierContinue(Content.back())) Content = Content.drop_back(); Content = Content.rtrim(); - if (Content.endswith("/*")) + if (Content.ends_with("/*")) return Content.size() - 2; return std::nullopt; } @@ -2408,12 +2408,12 @@ bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset) { Content = Content.substr(Pos + 1); // Complete after scope operators. - if (Content.endswith(".") || Content.endswith("->") || - Content.endswith("::") || Content.endswith("/*")) + if (Content.ends_with(".") || Content.ends_with("->") || + Content.ends_with("::") || Content.ends_with("/*")) return true; // Complete after `#include <` and #include `clear(); diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index e116a739774b85e09dcdef391519c476ab4daad8..f4e8e7e74a3beeee1f5f233a676f0b03d34d29fc 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -28,7 +28,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" -#include "llvm/TargetParser/Host.h" #include #include #include @@ -187,12 +186,6 @@ static std::string resolveDriver(llvm::StringRef Driver, bool FollowSymlink, } // namespace -CommandMangler::CommandMangler() { - Tokenizer = llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows() - ? llvm::cl::TokenizeWindowsCommandLine - : llvm::cl::TokenizeGNUCommandLine; -} - CommandMangler CommandMangler::detect() { CommandMangler Result; Result.ClangPath = detectClangPath(); @@ -213,14 +206,6 @@ void CommandMangler::operator()(tooling::CompileCommand &Command, if (Cmd.empty()) return; - // FS used for expanding response files. - // FIXME: ExpandResponseFiles appears not to provide the usual - // thread-safety guarantees, as the access to FS is not locked! - // For now, use the real FS, which is known to be threadsafe (if we don't - // use/change working directory, which ExpandResponseFiles doesn't). - auto FS = llvm::vfs::getRealFileSystem(); - tooling::addExpandedResponseFiles(Cmd, Command.Directory, Tokenizer, *FS); - auto &OptTable = clang::driver::getDriverOptTable(); // OriginalArgs needs to outlive ArgList. llvm::SmallVector OriginalArgs; @@ -338,7 +323,7 @@ void CommandMangler::operator()(tooling::CompileCommand &Command, }; llvm::erase_if(Cmd, [](llvm::StringRef Elem) { - return Elem.startswith("--save-temps") || Elem.startswith("-save-temps"); + return Elem.starts_with("--save-temps") || Elem.starts_with("-save-temps"); }); std::vector ToAppend; @@ -587,7 +572,7 @@ const ArgStripper::Rule *ArgStripper::matchingRule(llvm::StringRef Arg, continue; // not applicable to current driver mode if (BestRule && BestRule->Priority < R.Priority) continue; // lower-priority than best candidate. - if (!Arg.startswith(R.Text)) + if (!Arg.starts_with(R.Text)) continue; // current arg doesn't match the prefix string bool PrefixMatch = Arg.size() > R.Text.size(); // Can rule apply as an exact/prefix match? diff --git a/clang-tools-extra/clangd/CompileCommands.h b/clang-tools-extra/clangd/CompileCommands.h index 1b37f44f0b9db4b810053138bb12e1b141920a09..1ee0dba2dba80d27340af2d1d3c0e7928142c3ef 100644 --- a/clang-tools-extra/clangd/CompileCommands.h +++ b/clang-tools-extra/clangd/CompileCommands.h @@ -51,11 +51,8 @@ struct CommandMangler { llvm::StringRef TargetFile) const; private: - CommandMangler(); - Memoize> ResolvedDrivers; Memoize> ResolvedDriversNoFollow; - llvm::cl::TokenizerCallback Tokenizer; }; // Removes args from a command-line in a semantically-aware way. diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp index 0c9fc27643be87a7e4883a9d5a1d3797b10d31ad..5bb2eb4a9f803fb805244f87c139ac4cb4cdb2c5 100644 --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -490,7 +490,7 @@ struct FragmentCompiler { StringRef Str = StringRef(*Arg).trim(); // Don't support negating here, its handled if the item is in the Add or // Remove list. - if (Str.startswith("-") || Str.contains(',')) { + if (Str.starts_with("-") || Str.contains(',')) { diag(Error, "Invalid clang-tidy check name", Arg.Range); return; } diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp index 85f2592445f2a52449cb7f595dec7ab01649ce0d..b0cec65c39fa31dc641b395d43f7d3c4935af395 100644 --- a/clang-tools-extra/clangd/DumpAST.cpp +++ b/clang-tools-extra/clangd/DumpAST.cpp @@ -118,8 +118,8 @@ class DumpVisitor : public RecursiveASTVisitor { std::string getKind(const Decl *D) { return D->getDeclKindName(); } std::string getKind(const Stmt *S) { std::string Result = S->getStmtClassName(); - if (llvm::StringRef(Result).endswith("Stmt") || - llvm::StringRef(Result).endswith("Expr")) + if (llvm::StringRef(Result).ends_with("Stmt") || + llvm::StringRef(Result).ends_with("Expr")) Result.resize(Result.size() - 4); return Result; } diff --git a/clang-tools-extra/clangd/FileDistance.cpp b/clang-tools-extra/clangd/FileDistance.cpp index 09a9e80b7847a6a442d966192f74394f9d2ffad6..06c1a8bc92a862a6870df95039acc33334be9d5b 100644 --- a/clang-tools-extra/clangd/FileDistance.cpp +++ b/clang-tools-extra/clangd/FileDistance.cpp @@ -201,7 +201,7 @@ createScopeFileDistance(llvm::ArrayRef QueryScopes) { // place of enclosing namespaces (e.g. in implementation files). if (S == Preferred) Param.Cost = S == "" ? 4 : 0; - else if (Preferred.startswith(S) && !S.empty()) + else if (Preferred.starts_with(S) && !S.empty()) continue; // just rely on up-traversals. else Param.Cost = S == "" ? 6 : 2; diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp index 790ee9af8f4acfc8dbd12f764b9c5f51cc12bfd8..5b3e46a7b4dc167604a620540dae04f052487b78 100644 --- a/clang-tools-extra/clangd/FindSymbols.cpp +++ b/clang-tools-extra/clangd/FindSymbols.cpp @@ -41,8 +41,8 @@ struct ScoredSymbolGreater { // Returns true if \p Query can be found as a sub-sequence inside \p Scope. bool approximateScopeMatch(llvm::StringRef Scope, llvm::StringRef Query) { - assert(Scope.empty() || Scope.endswith("::")); - assert(Query.empty() || Query.endswith("::")); + assert(Scope.empty() || Scope.ends_with("::")); + assert(Query.empty() || Query.ends_with("::")); while (!Scope.empty() && !Query.empty()) { auto Colons = Scope.find("::"); assert(Colons != llvm::StringRef::npos); diff --git a/clang-tools-extra/clangd/Format.cpp b/clang-tools-extra/clangd/Format.cpp index c3e92636d1957285f00c2e6b82d43ea5b225e154..272a34d4ed79724fda8a8a4c99597ecfff99fc00 100644 --- a/clang-tools-extra/clangd/Format.cpp +++ b/clang-tools-extra/clangd/Format.cpp @@ -180,7 +180,7 @@ IncrementalChanges getIncrementalChangesAfterNewline(llvm::StringRef Code, bool NewLineIsComment = !commentMarker(Indentation).empty(); if (!CommentMarker.empty() && (NewLineIsComment || !commentMarker(NextLine).empty() || - (!TrailingTrim.empty() && !TrailingTrim.startswith("//")))) { + (!TrailingTrim.empty() && !TrailingTrim.starts_with("//")))) { // We indent the new comment to match the previous one. StringRef PreComment = Leading.take_front(CommentMarker.data() - Leading.data()); @@ -197,8 +197,8 @@ IncrementalChanges getIncrementalChangesAfterNewline(llvm::StringRef Code, } // If we put a the newline inside a {} pair, put } on its own line... - if (CommentMarker.empty() && Leading.endswith("{") && - Trailing.startswith("}")) { + if (CommentMarker.empty() && Leading.ends_with("{") && + Trailing.starts_with("}")) { cantFail( Result.Changes.add(replacement(Code, Trailing.take_front(1), "\n}"))); // ...and format it. diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp index d1833759917a30ff7f0caaea529f54d389e89625..5bec7966a9c3a9db7a48cb7590bf0a4956ae6859 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -18,6 +18,7 @@ #include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/CompilationDatabasePluginRegistry.h" #include "clang/Tooling/JSONCompilationDatabase.h" +#include "clang/Tooling/Tooling.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" @@ -25,6 +26,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Support/Path.h" #include "llvm/Support/VirtualFileSystem.h" +#include "llvm/TargetParser/Host.h" #include #include #include @@ -244,7 +246,16 @@ static std::unique_ptr parseJSON(PathRef Path, llvm::StringRef Data, std::string &Error) { if (auto CDB = tooling::JSONCompilationDatabase::loadFromBuffer( Data, Error, tooling::JSONCommandLineSyntax::AutoDetect)) { - return tooling::inferMissingCompileCommands(std::move(CDB)); + // FS used for expanding response files. + // FIXME: ExpandResponseFilesDatabase appears not to provide the usual + // thread-safety guarantees, as the access to FS is not locked! + // For now, use the real FS, which is known to be threadsafe (if we don't + // use/change working directory, which ExpandResponseFilesDatabase doesn't). + // NOTE: response files have to be expanded before inference because + // inference needs full command line to check/fix driver mode and file type. + auto FS = llvm::vfs::getRealFileSystem(); + return tooling::inferMissingCompileCommands( + expandResponseFiles(std::move(CDB), std::move(FS))); } return nullptr; } @@ -744,6 +755,22 @@ OverlayCDB::getCompileCommand(PathRef File) const { if (It != Commands.end()) Cmd = It->second; } + if (Cmd) { + // FS used for expanding response files. + // FIXME: ExpandResponseFiles appears not to provide the usual + // thread-safety guarantees, as the access to FS is not locked! + // For now, use the real FS, which is known to be threadsafe (if we don't + // use/change working directory, which ExpandResponseFiles doesn't). + auto FS = llvm::vfs::getRealFileSystem(); + auto Tokenizer = llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows() + ? llvm::cl::TokenizeWindowsCommandLine + : llvm::cl::TokenizeGNUCommandLine; + // Compile command pushed via LSP protocol may have response files that need + // to be expanded before further processing. For CDB for files it happens in + // the main CDB when reading it from the JSON file. + tooling::addExpandedResponseFiles(Cmd->CommandLine, Cmd->Directory, + Tokenizer, *FS); + } if (!Cmd) Cmd = DelegatingCDB::getCompileCommand(File); if (!Cmd) diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp index 6005069be01160df40bcd2e24c4c83995e915113..076e636e0e2819a05ac7cb08909de62c74dc9a31 100644 --- a/clang-tools-extra/clangd/Headers.cpp +++ b/clang-tools-extra/clangd/Headers.cpp @@ -82,7 +82,7 @@ public: if (File) { auto IncludingFileEntry = SM.getFileEntryRefForID(SM.getFileID(HashLoc)); if (!IncludingFileEntry) { - assert(SM.getBufferName(HashLoc).startswith("<") && + assert(SM.getBufferName(HashLoc).starts_with("<") && "Expected #include location to be a file or "); // Treat as if included from the main file. IncludingFileEntry = SM.getFileEntryRefForID(MainFID); @@ -131,7 +131,7 @@ private: }; bool isLiteralInclude(llvm::StringRef Include) { - return Include.startswith("<") || Include.startswith("\""); + return Include.starts_with("<") || Include.starts_with("\""); } bool HeaderFile::valid() const { @@ -316,7 +316,7 @@ IncludeInserter::insert(llvm::StringRef VerbatimHeader, std::optional Edit; if (auto Insertion = Inserter.insert(VerbatimHeader.trim("\"<>"), - VerbatimHeader.startswith("<"), Directive)) + VerbatimHeader.starts_with("<"), Directive)) Edit = replacementToEdit(Code, *Insertion); return Edit; } diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index a868d3bb4e3fa1d0a26ab02611efdc11e37bd699..82323fe16c82b6e4e72905e6fbd4b32946f9dcf6 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -960,7 +960,7 @@ std::optional getHoverContents(const Attr *A, ParsedAST &AST) { } bool isParagraphBreak(llvm::StringRef Rest) { - return Rest.ltrim(" \t").startswith("\n"); + return Rest.ltrim(" \t").starts_with("\n"); } bool punctuationIndicatesLineBreak(llvm::StringRef Line) { @@ -984,7 +984,7 @@ bool isHardLineBreakIndicator(llvm::StringRef Rest) { if (llvm::isDigit(Rest.front())) { llvm::StringRef AfterDigit = Rest.drop_while(llvm::isDigit); - if (AfterDigit.startswith(".") || AfterDigit.startswith(")")) + if (AfterDigit.starts_with(".") || AfterDigit.starts_with(")")) return true; } return false; diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index dda7c9f581f69c7b03517416b2ce2f08cb279d79..2f34c949349200337329b4456aff03dc891c4c57 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -95,7 +95,7 @@ bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST, // Since most private -> public mappings happen in a verbatim way, we // check textually here. This might go wrong in presence of symlinks or // header mappings. But that's not different than rest of the places. - if (AST.tuPath().endswith(PHeader)) + if (AST.tuPath().ends_with(PHeader)) return false; } } diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp index 0c4d011b80372ba95dfdda7b8b2f299b90bc943f..fadd1105691fc01e183ee19e8d66cbb482eaf45d 100644 --- a/clang-tools-extra/clangd/IncludeFixer.cpp +++ b/clang-tools-extra/clangd/IncludeFixer.cpp @@ -416,7 +416,7 @@ std::optional extractUnresolvedNameCheaply( // namespace clang { clangd::X; } // In this case, we use the "typo" specifier as extra scope instead // of using the scope assumed by sema. - if (!Spelling || llvm::StringRef(SpecifiedNS).endswith(*Spelling)) { + if (!Spelling || llvm::StringRef(SpecifiedNS).ends_with(*Spelling)) { Result.ResolvedScope = std::move(SpecifiedNS); } else { Result.UnresolvedScope = std::move(*Spelling); diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp index b540c273cbd59672b07c8eede970e2824f17ca53..5722ca8f66eb72069edb2fa4dcc2a32d96c4ce00 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -286,7 +286,7 @@ std::string summarizeExpr(const Expr *E) { // Step through implicit nodes that clang doesn't classify as such. std::string VisitCXXMemberCallExpr(const CXXMemberCallExpr *E) { // Call to operator bool() inside if (X): dispatch to X. - if (E->getNumArgs() == 0 && + if (E->getNumArgs() == 0 && E->getMethodDecl() && E->getMethodDecl()->getDeclName().getNameKind() == DeclarationName::CXXConversionFunctionName && E->getSourceRange() == @@ -1040,7 +1040,7 @@ private: if (!SourcePrefix.consume_back(ParamName)) return false; SourcePrefix = SourcePrefix.rtrim(IgnoreChars); - return SourcePrefix.endswith("/*"); + return SourcePrefix.ends_with("/*"); } // If "E" spells a single unqualified identifier, return that name. diff --git a/clang-tools-extra/clangd/JSONTransport.cpp b/clang-tools-extra/clangd/JSONTransport.cpp index 9dc0df807aa3463116093cdee3610bd759538529..346c7dfb66a1dbb01709e31ed6386470f42749b4 100644 --- a/clang-tools-extra/clangd/JSONTransport.cpp +++ b/clang-tools-extra/clangd/JSONTransport.cpp @@ -240,7 +240,7 @@ bool JSONTransport::readStandardMessage(std::string &JSON) { // We allow comments in headers. Technically this isn't part // of the LSP specification, but makes writing tests easier. - if (LineRef.startswith("#")) + if (LineRef.starts_with("#")) continue; // Content-Length is a mandatory header, and the only one we handle. @@ -304,7 +304,7 @@ bool JSONTransport::readDelimitedMessage(std::string &JSON) { while (readLine(In, Line)) { InMirror << Line; auto LineRef = Line.str().trim(); - if (LineRef.startswith("#")) // comment + if (LineRef.starts_with("#")) // comment continue; // found a delimiter diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index edd0f77b1031ef03e4da50a87948883ff671e74f..d91ce7283ecee44d5d3895c3431cc9f581b913f2 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -288,7 +288,7 @@ public: if (Glob) { // Is this clang-diagnostic-*, or *, or so? // (We ignore all other types of globs). - if (CDPrefix.startswith(Check)) { + if (CDPrefix.starts_with(Check)) { Default = Enable; Exceptions.clear(); } diff --git a/clang-tools-extra/clangd/PathMapping.cpp b/clang-tools-extra/clangd/PathMapping.cpp index 2554d34d96b9dfdb323f567a4465f9d9454c2169..4b93ff2c60c5c6035920c4cae17f7d77a9485b9d 100644 --- a/clang-tools-extra/clangd/PathMapping.cpp +++ b/clang-tools-extra/clangd/PathMapping.cpp @@ -21,7 +21,7 @@ std::optional doPathMapping(llvm::StringRef S, PathMapping::Direction Dir, const PathMappings &Mappings) { // Return early to optimize for the common case, wherein S is not a file URI - if (!S.startswith("file://")) + if (!S.starts_with("file://")) return std::nullopt; auto Uri = URI::parse(S); if (!Uri) { diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index e44aee2d47819468636501f62dbc68be226d225a..a6370649f5ad1cf3a1810c3499cbac0890b8363c 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -844,7 +844,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) { if (!S.containerName.empty()) { O << S.containerName; llvm::StringRef ContNameRef; - if (!ContNameRef.endswith("::")) { + if (!ContNameRef.ends_with("::")) { O << " "; } } diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp index 31323c08cf1ddf9086a1b583fcce7e5ad911f95a..835038423fdf3729ebff38e3d784262bb2dce855 100644 --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -891,10 +891,10 @@ llvm::StringSet<> collectWords(llvm::StringRef Content) { static bool isLikelyIdentifier(llvm::StringRef Word, llvm::StringRef Before, llvm::StringRef After) { // `foo` is an identifier. - if (Before.endswith("`") && After.startswith("`")) + if (Before.ends_with("`") && After.starts_with("`")) return true; // In foo::bar, both foo and bar are identifiers. - if (Before.endswith("::") || After.startswith("::")) + if (Before.ends_with("::") || After.starts_with("::")) return true; // Doxygen tags like \c foo indicate identifiers. // Don't search too far back. @@ -1180,7 +1180,7 @@ EligibleRegion getEligiblePoints(llvm::StringRef Code, } // Ignore namespaces that are not a prefix of the target. - if (!FullyQualifiedName.startswith(CurrentNamespace)) + if (!FullyQualifiedName.starts_with(CurrentNamespace)) return; // Prefer the namespace that shares the longest prefix with target. @@ -1213,14 +1213,14 @@ bool isHeaderFile(llvm::StringRef FileName, bool isProtoFile(SourceLocation Loc, const SourceManager &SM) { auto FileName = SM.getFilename(Loc); - if (!FileName.endswith(".proto.h") && !FileName.endswith(".pb.h")) + if (!FileName.ends_with(".proto.h") && !FileName.ends_with(".pb.h")) return false; auto FID = SM.getFileID(Loc); // All proto generated headers should start with this line. static const char *ProtoHeaderComment = "// Generated by the protocol buffer compiler. DO NOT EDIT!"; // Double check that this is an actual protobuf header. - return SM.getBufferData(FID).startswith(ProtoHeaderComment); + return SM.getBufferData(FID).starts_with(ProtoHeaderComment); } SourceLocation translatePreamblePatchLocation(SourceLocation Loc, @@ -1230,7 +1230,7 @@ SourceLocation translatePreamblePatchLocation(SourceLocation Loc, auto IncludeLoc = SM.getIncludeLoc(DefFile); // Preamble patch is included inside the builtin file. if (IncludeLoc.isValid() && SM.isWrittenInBuiltinFile(IncludeLoc) && - FE->getName().endswith(PreamblePatch::HeaderName)) { + FE->getName().ends_with(PreamblePatch::HeaderName)) { auto Presumed = SM.getPresumedLoc(Loc); // Check that line directive is pointing at main file. if (Presumed.isValid() && Presumed.getFileID().isInvalid() && diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp index ea98c7d948a2f6de1976fc5924fff7fa79370f40..d4b9b173d149da06946bd16bc6b88fb0074a3b4d 100644 --- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp +++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp @@ -146,13 +146,13 @@ struct DriverArgs { Stdlib = Cmd.CommandLine[I + 1]; } else if (Arg.consume_front("-stdlib=")) { Stdlib = Arg.str(); - } else if (Arg.startswith("-specs=")) { + } else if (Arg.starts_with("-specs=")) { // clang requires a single token like `-specs=file` or `--specs=file`, // but gcc will accept two tokens like `--specs file`. Since the // compilation database is presumably correct, we just forward the flags // as-is. Specs.push_back(Arg.str()); - } else if (Arg.startswith("--specs=")) { + } else if (Arg.starts_with("--specs=")) { Specs.push_back(Arg.str()); } else if (Arg == "--specs" && I + 1 < E) { Specs.push_back(Arg.str()); @@ -282,7 +282,7 @@ std::optional parseDriverOutput(llvm::StringRef Output) { if (!SeenIncludes && Line.trim() == SIS) { SeenIncludes = true; State = IncludesExtracting; - } else if (!SeenTarget && Line.trim().startswith(TS)) { + } else if (!SeenTarget && Line.trim().starts_with(TS)) { SeenTarget = true; llvm::StringRef TargetLine = Line.trim(); TargetLine.consume_front(TS); @@ -448,7 +448,7 @@ tooling::CompileCommand &setTarget(tooling::CompileCommand &Cmd, if (!Target.empty()) { // We do not want to override existing target with extracted one. for (llvm::StringRef Arg : Cmd.CommandLine) { - if (Arg == "-target" || Arg.startswith("--target=")) + if (Arg == "-target" || Arg.starts_with("--target=")) return Cmd; } // Just append when `--` isn't present. diff --git a/clang-tools-extra/clangd/URI.cpp b/clang-tools-extra/clangd/URI.cpp index ca65df329aeebf3c3d709cd9c07c9b1c52002c9f..11d70dc917f56bf9f1c191caf3850d7ed3a4f1a8 100644 --- a/clang-tools-extra/clangd/URI.cpp +++ b/clang-tools-extra/clangd/URI.cpp @@ -38,7 +38,7 @@ public: llvm::Expected getAbsolutePath(llvm::StringRef Authority, llvm::StringRef Body, llvm::StringRef /*HintPath*/) const override { - if (!Body.startswith("/")) + if (!Body.starts_with("/")) return error("File scheme: expect body to be an absolute path starting " "with '/': {0}", Body); @@ -153,7 +153,7 @@ URI::URI(llvm::StringRef Scheme, llvm::StringRef Authority, llvm::StringRef Body) : Scheme(Scheme), Authority(Authority), Body(Body) { assert(!Scheme.empty()); - assert((Authority.empty() || Body.startswith("/")) && + assert((Authority.empty() || Body.starts_with("/")) && "URI body must start with '/' when authority is present."); } @@ -165,8 +165,7 @@ std::string URI::toString() const { return Result; // If authority if empty, we only print body if it starts with "/"; otherwise, // the URI is invalid. - if (!Authority.empty() || llvm::StringRef(Body).startswith("/")) - { + if (!Authority.empty() || llvm::StringRef(Body).starts_with("/")) { Result.append("//"); percentEncode(Authority, Result); } diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp index 9ba4d7a95415bc08968cb23d0a8b5397ac135166..42eeba36a80e43eaa5bc9f87f454297f8ea409f1 100644 --- a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +++ b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp @@ -670,6 +670,7 @@ const std::pair IncludeMappings[] = { {"bits/types.h", ""}, {"bits/types/siginfo_t.h", ""}, {"bits/types/struct_itimerspec.h", ""}, + {"bits/types/struct_rusage.h", ""}, {"bits/uio.h", ""}, {"bits/ustat.h", ""}, {"bits/utmp.h", ""}, diff --git a/clang-tools-extra/clangd/index/Merge.cpp b/clang-tools-extra/clangd/index/Merge.cpp index 9687b36252e12ceeb73df70e43a791ffb402a63f..8221d4b1f44405abab5bb6fdf0a0a73783cdfee3 100644 --- a/clang-tools-extra/clangd/index/Merge.cpp +++ b/clang-tools-extra/clangd/index/Merge.cpp @@ -197,7 +197,7 @@ static bool prefer(const SymbolLocation &L, const SymbolLocation &R) { auto HasCodeGenSuffix = [](const SymbolLocation &Loc) { constexpr static const char *CodegenSuffixes[] = {".proto"}; return llvm::any_of(CodegenSuffixes, [&](llvm::StringRef Suffix) { - return llvm::StringRef(Loc.FileURI).endswith(Suffix); + return llvm::StringRef(Loc.FileURI).ends_with(Suffix); }); }; return HasCodeGenSuffix(L) && !HasCodeGenSuffix(R); diff --git a/clang-tools-extra/clangd/index/Serialization.cpp b/clang-tools-extra/clangd/index/Serialization.cpp index b905f580c281c9f750601b2df420696732601357..72a4e8b007668f4a6629afdefecc89b764690a7b 100644 --- a/clang-tools-extra/clangd/index/Serialization.cpp +++ b/clang-tools-extra/clangd/index/Serialization.cpp @@ -692,7 +692,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const IndexFileOut &O) { llvm::Expected readIndexFile(llvm::StringRef Data, SymbolOrigin Origin) { - if (Data.startswith("RIFF")) { + if (Data.starts_with("RIFF")) { return readRIFF(Data, Origin); } if (auto YAMLContents = readYAML(Data, Origin)) { diff --git a/clang-tools-extra/clangd/index/StdLib.cpp b/clang-tools-extra/clangd/index/StdLib.cpp index 390c2e41f6c0f97d95f0feeaae7f1e411d5cefb5..921ab5d1c96d5cf0f5b36c7779667aca6a962883 100644 --- a/clang-tools-extra/clangd/index/StdLib.cpp +++ b/clang-tools-extra/clangd/index/StdLib.cpp @@ -167,7 +167,7 @@ SymbolSlab filter(SymbolSlab Slab, const StdLibLocation &Loc) { R.first->second = llvm::any_of( StdLibURIPrefixes, [&, URIStr(llvm::StringRef(URI))](const std::string &Prefix) { - return URIStr.startswith(Prefix); + return URIStr.starts_with(Prefix); }); } } diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index aac6676a995fedfd28fb12aabecf30fe76a132c7..7ef4b15febad22f863b7a6c4490823d3e61acf0e 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -262,7 +262,7 @@ public: if (Canonical.empty()) return ""; // If we had a mapping, always use it. - assert(Canonical.startswith("<") || Canonical.startswith("\"")); + assert(Canonical.starts_with("<") || Canonical.starts_with("\"")); return Canonical; } @@ -414,7 +414,7 @@ private: PP->getHeaderSearchInfo())) { // A .inc or .def file is often included into a real header to define // symbols (e.g. LLVM tablegen files). - if (Filename.endswith(".inc") || Filename.endswith(".def")) + if (Filename.ends_with(".inc") || Filename.ends_with(".def")) // Don't use cache reentrantly due to iterator invalidation. return getIncludeHeaderUncached(SM.getFileID(SM.getIncludeLoc(FID))); // Conservatively refuse to insert #includes to files without guards. @@ -826,22 +826,8 @@ void SymbolCollector::setIncludeLocation(const Symbol &S, SourceLocation DefLoc, // We update providers for a symbol with each occurence, as SymbolCollector // might run while parsing, rather than at the end of a translation unit. // Hence we see more and more redecls over time. - auto [It, Inserted] = SymbolProviders.try_emplace(S.ID); - auto Headers = + SymbolProviders[S.ID] = include_cleaner::headersForSymbol(Sym, SM, Opts.PragmaIncludes); - if (Headers.empty()) - return; - - auto *HeadersIter = Headers.begin(); - include_cleaner::Header H = *HeadersIter; - while (HeadersIter != Headers.end() && - H.kind() == include_cleaner::Header::Physical && - !tooling::isSelfContainedHeader(H.physical(), SM, - PP->getHeaderSearchInfo())) { - H = *HeadersIter; - HeadersIter++; - } - It->second = H; } llvm::StringRef getStdHeader(const Symbol *S, const LangOptions &LangOpts) { @@ -889,7 +875,7 @@ void SymbolCollector::finish() { llvm::DenseMap HeaderSpelling; // Fill in IncludeHeaders. // We delay this until end of TU so header guards are all resolved. - for (const auto &[SID, OptionalProvider] : SymbolProviders) { + for (const auto &[SID, Providers] : SymbolProviders) { const Symbol *S = Symbols.find(SID); if (!S) continue; @@ -931,9 +917,27 @@ void SymbolCollector::finish() { continue; } - assert(Directives == Symbol::Include); // For #include's, use the providers computed by the include-cleaner // library. + assert(Directives == Symbol::Include); + // Ignore providers that are not self-contained, this is especially + // important for symbols defined in the main-file. We want to prefer the + // header, if possible. + // TODO: Limit this to specifically ignore main file, when we're indexing a + // non-header file? + auto SelfContainedProvider = + [this](llvm::ArrayRef Providers) + -> std::optional { + for (const auto &H : Providers) { + if (H.kind() != include_cleaner::Header::Physical) + return H; + if (tooling::isSelfContainedHeader(H.physical(), PP->getSourceManager(), + PP->getHeaderSearchInfo())) + return H; + } + return std::nullopt; + }; + const auto OptionalProvider = SelfContainedProvider(Providers); if (!OptionalProvider) continue; const auto &H = *OptionalProvider; diff --git a/clang-tools-extra/clangd/index/SymbolCollector.h b/clang-tools-extra/clangd/index/SymbolCollector.h index 10765020de518bd6a163ce5cb50816b048c28393..20116fca7c51e3959c42584d2367760145253227 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.h +++ b/clang-tools-extra/clangd/index/SymbolCollector.h @@ -15,18 +15,25 @@ #include "index/Relation.h" #include "index/Symbol.h" #include "index/SymbolID.h" +#include "index/SymbolLocation.h" #include "index/SymbolOrigin.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Index/IndexDataConsumer.h" #include "clang/Index/IndexSymbol.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include #include #include +#include +#include namespace clang { namespace clangd { @@ -177,7 +184,7 @@ private: // Providers for Symbol.IncludeHeaders. // The final spelling is calculated in finish(). - llvm::DenseMap> + llvm::DenseMap> SymbolProviders; // Files which contain ObjC symbols. // This is finalized and used in finish(). diff --git a/clang-tools-extra/clangd/index/dex/Dex.cpp b/clang-tools-extra/clangd/index/dex/Dex.cpp index 8f504fb9b7ea304ef2f11d1bb1567dcdf1d7956a..19dc3080f9f897b8c85c4f501b0789378ee5ae82 100644 --- a/clang-tools-extra/clangd/index/dex/Dex.cpp +++ b/clang-tools-extra/clangd/index/dex/Dex.cpp @@ -395,7 +395,7 @@ generateProximityURIs(llvm::StringRef URI) { return Result; } // The root foo://bar/ is a proximity URI. - if (Path.startswith("/")) + if (Path.starts_with("/")) Result.push_back(URI.substr(0, Path.begin() + 1 - URI.data())); return Result; } diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp index 392960d6d6660d130b030b0f936ff385d2d804db..cea59ae409914c048d542a0dec254ee144e343fd 100644 --- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp +++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp @@ -372,7 +372,7 @@ struct { }; std::unique_ptr openIndex(llvm::StringRef Index) { - return Index.startswith("remote:") + return Index.starts_with("remote:") ? remote::getClient(Index.drop_front(strlen("remote:")), ProjectRoot) : loadIndex(Index, SymbolOrigin::Static, /*UseDex=*/true); @@ -424,7 +424,7 @@ int main(int argc, const char *argv[]) { llvm::cl::ResetCommandLineParser(); // We reuse it for REPL commands. llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - bool RemoteMode = llvm::StringRef(IndexLocation).startswith("remote:"); + bool RemoteMode = llvm::StringRef(IndexLocation).starts_with("remote:"); if (RemoteMode && ProjectRoot.empty()) { llvm::errs() << "--project-root is required in remote mode\n"; return -1; diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp index e108d4d0b057ba2374ef87da9fe05f0ab4034adf..4ef3ab6f9af9c2fcb7fde580aadd7b5862b9fabd 100644 --- a/clang-tools-extra/clangd/index/remote/server/Server.cpp +++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp @@ -451,7 +451,7 @@ std::unique_ptr makeLogger(llvm::StringRef LogPrefix, void log(Level L, const char *Fmt, const llvm::formatv_object_base &Message) override { if (Context::current().get(CurrentRequest) == nullptr || - llvm::StringRef(Fmt).startswith("[public]")) + llvm::StringRef(Fmt).starts_with("[public]")) return StreamLogger::log(L, Fmt, Message); if (L >= Error) return StreamLogger::log(L, Fmt, diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp index ca96da34e092011433717bc7769ba6ae46bbb783..00c05ebdb521663393d65ff2c0ce835fe54c036c 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -352,7 +352,7 @@ bool AddUsing::prepare(const Selection &Inputs) { splitQualifiedName(SpelledRange.text(SM)); QualifierToSpell = getNNSLAsString( QualifierToRemove, Inputs.AST->getASTContext().getPrintingPolicy()); - if (!llvm::StringRef(QualifierToSpell).endswith(SpelledQualifier) || + if (!llvm::StringRef(QualifierToSpell).ends_with(SpelledQualifier) || SpelledName.empty()) return false; // What's spelled doesn't match the qualifier. return true; diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index b84ae04072f2c19b2afd9098cda80b9a57ef164b..fef827a801c33974ef1118d31ccc402af0bb9c73 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -71,7 +71,7 @@ std::optional getSourceFile(llvm::StringRef FileName, // Returns std::nullopt if TargetNS is not a prefix of CurContext. std::optional findContextForNS(llvm::StringRef TargetNS, const DeclContext *CurContext) { - assert(TargetNS.empty() || TargetNS.endswith("::")); + assert(TargetNS.empty() || TargetNS.ends_with("::")); // Skip any non-namespace contexts, e.g. TagDecls, functions/methods. CurContext = CurContext->getEnclosingNamespaceContext(); // If TargetNS is empty, it means global ns, which is translation unit. @@ -91,7 +91,7 @@ findContextForNS(llvm::StringRef TargetNS, const DeclContext *CurContext) { llvm::StringRef CurrentContextNS(TargetContextNS); // If TargetNS is not a prefix of CurrentContext, there's no way to reach // it. - if (!CurrentContextNS.startswith(TargetNS)) + if (!CurrentContextNS.starts_with(TargetNS)) return std::nullopt; while (CurrentContextNS != TargetNS) { diff --git a/clang-tools-extra/clangd/support/Markup.cpp b/clang-tools-extra/clangd/support/Markup.cpp index 4d17a2bf2b2b869358e8c58e2ba6215957ed286b..63aff96b02056d3c43360c1df2536f5c0dd24eeb 100644 --- a/clang-tools-extra/clangd/support/Markup.cpp +++ b/clang-tools-extra/clangd/support/Markup.cpp @@ -47,7 +47,7 @@ bool looksLikeTag(llvm::StringRef Contents) { for (; !Contents.empty(); Contents = Contents.drop_front()) { if (llvm::isAlnum(Contents.front()) || llvm::isSpace(Contents.front())) continue; - if (Contents.front() == '>' || Contents.startswith("/>")) + if (Contents.front() == '>' || Contents.starts_with("/>")) return true; // May close the tag. if (Contents.front() == '=') return true; // Don't try to parse attribute values. @@ -75,7 +75,7 @@ bool needsLeadingEscape(char C, llvm::StringRef Before, llvm::StringRef After, }; auto IsBullet = [&]() { return StartsLine && Before.empty() && - (After.empty() || After.startswith(" ")); + (After.empty() || After.starts_with(" ")); }; auto SpaceSurrounds = [&]() { return (After.empty() || llvm::isSpace(After.front())) && @@ -94,12 +94,12 @@ bool needsLeadingEscape(char C, llvm::StringRef Before, llvm::StringRef After, // anywhere (including on another line). We must escape them all. return true; case '~': // Code block - return StartsLine && Before.empty() && After.startswith("~~"); + return StartsLine && Before.empty() && After.starts_with("~~"); case '#': { // ATX heading. if (!StartsLine || !Before.empty()) return false; llvm::StringRef Rest = After.ltrim(C); - return Rest.empty() || Rest.startswith(" "); + return Rest.empty() || Rest.starts_with(" "); } case ']': // Link or link reference. // We escape ] rather than [ here, because it's more constrained: @@ -109,7 +109,7 @@ bool needsLeadingEscape(char C, llvm::StringRef Before, llvm::StringRef After, // ] by itself is a shortcut link // ][...] is an out-of-line link // Because we never emit link references, we don't need to handle these. - return After.startswith(":") || After.startswith("("); + return After.starts_with(":") || After.starts_with("("); case '=': // Setex heading. return RulerLength() > 0; case '_': // Horizontal ruler or matched delimiter. @@ -145,7 +145,7 @@ bool needsLeadingEscape(char C, llvm::StringRef Before, llvm::StringRef After, case '.': // Numbered list indicator. Escape 12. -> 12\. at start of line. case ')': return StartsLine && !Before.empty() && - llvm::all_of(Before, llvm::isDigit) && After.startswith(" "); + llvm::all_of(Before, llvm::isDigit) && After.starts_with(" "); default: return false; } @@ -180,12 +180,12 @@ std::string renderInlineBlock(llvm::StringRef Input) { } // If results starts with a backtick, add spaces on both sides. The spaces // are ignored by markdown renderers. - if (llvm::StringRef(R).startswith("`") || llvm::StringRef(R).endswith("`")) + if (llvm::StringRef(R).starts_with("`") || llvm::StringRef(R).ends_with("`")) return "` " + std::move(R) + " `"; // Markdown render should ignore first and last space if both are there. We // add an extra pair of spaces in that case to make sure we render what the // user intended. - if (llvm::StringRef(R).startswith(" ") && llvm::StringRef(R).endswith(" ")) + if (llvm::StringRef(R).starts_with(" ") && llvm::StringRef(R).ends_with(" ")) return "` " + std::move(R) + " `"; return "`" + std::move(R) + "`"; } @@ -250,7 +250,7 @@ std::string renderBlocks(llvm::ArrayRef> Children, return !llvm::StringRef(TrimmedText.data(), &C - TrimmedText.data() + 1) // We allow at most two newlines. - .endswith("\n\n\n"); + .ends_with("\n\n\n"); }); return AdjustedResult; @@ -301,7 +301,7 @@ private: // Inserts two spaces after each `\n` to indent each line. First line is not // indented. std::string indentLines(llvm::StringRef Input) { - assert(!Input.endswith("\n") && "Input should've been trimmed."); + assert(!Input.ends_with("\n") && "Input should've been trimmed."); std::string IndentedR; // We'll add 2 spaces after each new line. IndentedR.reserve(Input.size() + Input.count('\n') * 2); diff --git a/clang-tools-extra/clangd/support/ThreadsafeFS.cpp b/clang-tools-extra/clangd/support/ThreadsafeFS.cpp index 87babef4ee8c88aaaa50461e4fe124a4cac37276..0e249d07d2fd9141bc2224d8e702aee49a59182c 100644 --- a/clang-tools-extra/clangd/support/ThreadsafeFS.cpp +++ b/clang-tools-extra/clangd/support/ThreadsafeFS.cpp @@ -39,7 +39,7 @@ public: // Try to guess preamble files, they can be memory-mapped even on Windows as // clangd has exclusive access to those and nothing else should touch them. llvm::StringRef FileName = llvm::sys::path::filename(Path); - if (FileName.startswith("preamble-") && FileName.endswith(".pch")) + if (FileName.starts_with("preamble-") && FileName.ends_with(".pch")) return File; return std::unique_ptr(new VolatileFile(std::move(*File))); } diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index b5c4d145619df33a5da26c5704f79776d6d4c3d6..5e9d8d53625b68663cda75790c40e39af03f7e9b 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -24,6 +24,7 @@ // //===----------------------------------------------------------------------===// +#include "Check.h" #include "../clang-tidy/ClangTidyModule.h" #include "../clang-tidy/ClangTidyModuleRegistry.h" #include "../clang-tidy/ClangTidyOptions.h" @@ -82,36 +83,8 @@ namespace clang { namespace clangd { namespace { -// These will never be shown in --help, ClangdMain doesn't list the category. -llvm::cl::opt CheckTidyTime{ - "check-tidy-time", - llvm::cl::desc("Print the overhead of checks matching this glob"), - llvm::cl::init("")}; -llvm::cl::opt CheckFileLines{ - "check-lines", - llvm::cl::desc( - "Limits the range of tokens in -check file on which " - "various features are tested. Example --check-lines=3-7 restricts " - "testing to lines 3 to 7 (inclusive) or --check-lines=5 to restrict " - "to one line. Default is testing entire file."), - llvm::cl::init("")}; -llvm::cl::opt CheckLocations{ - "check-locations", - llvm::cl::desc( - "Runs certain features (e.g. hover) at each point in the file. " - "Somewhat slow."), - llvm::cl::init(true)}; -llvm::cl::opt CheckCompletion{ - "check-completion", - llvm::cl::desc("Run code-completion at each point (slow)"), - llvm::cl::init(false)}; -llvm::cl::opt CheckWarnings{ - "check-warnings", - llvm::cl::desc("Print warnings as well as errors"), - llvm::cl::init(false)}; - // Print the diagnostics meeting severity threshold, and return count of errors. -unsigned showErrors(llvm::ArrayRef Diags) { +unsigned showErrors(llvm::ArrayRef Diags, bool CheckWarnings) { unsigned ErrCount = 0; for (const auto &D : Diags) { if (D.Severity >= DiagnosticsEngine::Error || CheckWarnings) @@ -144,6 +117,7 @@ class Checker { // from constructor std::string File; ClangdLSPServer::Options Opts; + ClangdCheckOptions CheckOpts; // from buildCommand tooling::CompileCommand Cmd; // from buildInvocation @@ -159,8 +133,9 @@ public: // Number of non-fatal errors seen. unsigned ErrCount = 0; - Checker(llvm::StringRef File, const ClangdLSPServer::Options &Opts) - : File(File), Opts(Opts) {} + Checker(llvm::StringRef File, const ClangdLSPServer::Options &Opts, + const ClangdCheckOptions &CheckOpts) + : File(File), Opts(Opts), CheckOpts(CheckOpts) {} // Read compilation database and choose a compile command for the file. bool buildCommand(const ThreadsafeFS &TFS) { @@ -217,7 +192,7 @@ public: Invocation = buildCompilerInvocation(Inputs, CaptureInvocationDiags, &CC1Args); auto InvocationDiags = CaptureInvocationDiags.take(); - ErrCount += showErrors(InvocationDiags); + ErrCount += showErrors(InvocationDiags, CheckOpts.CheckWarnings); log("internal (cc1) args are: {0}", printArgv(CC1Args)); if (!Invocation) { elog("Failed to parse command line"); @@ -248,7 +223,7 @@ public: elog("Failed to build preamble"); return false; } - ErrCount += showErrors(Preamble->Diags); + ErrCount += showErrors(Preamble->Diags, CheckOpts.CheckWarnings); log("Building AST..."); AST = ParsedAST::build(File, Inputs, std::move(Invocation), @@ -258,16 +233,17 @@ public: return false; } ErrCount += - showErrors(AST->getDiagnostics().drop_front(Preamble->Diags.size())); + showErrors(AST->getDiagnostics().drop_front(Preamble->Diags.size()), + CheckOpts.CheckWarnings); if (Opts.BuildDynamicSymbolIndex) { log("Indexing AST..."); Index.updateMain(File, *AST); } - if (!CheckTidyTime.empty()) { + if (CheckOpts.CheckTidyTime) { if (!CLANGD_TIDY_CHECKS) { - elog("-{0} requires -DCLANGD_TIDY_CHECKS!", CheckTidyTime.ArgStr); + elog("-check-tidy-time requires -DCLANGD_TIDY_CHECKS!"); return false; } #ifndef NDEBUG @@ -349,7 +325,8 @@ public: } }; - for (const auto& Check : listTidyChecks(CheckTidyTime)) { + for (const auto &Check : + listTidyChecks(CheckOpts.CheckTidyTime.value_or(""))) { // vlog the check name in case we crash! vlog(" Timing {0}", Check); double Fraction = Measure(Check); @@ -433,7 +410,7 @@ public: unsigned DocHighlights = findDocumentHighlights(*AST, Pos).size(); vlog(" documentHighlight: {0}", DocHighlights); - if (CheckCompletion) { + if (CheckOpts.CheckCompletion) { Position EndPos = offsetToPosition(Inputs.Contents, End); auto CC = codeComplete(File, EndPos, Preamble.get(), Inputs, CCOpts); vlog(" code completion: {0}", @@ -446,11 +423,12 @@ public: } // namespace bool check(llvm::StringRef File, const ThreadsafeFS &TFS, - const ClangdLSPServer::Options &Opts) { + const ClangdLSPServer::Options &Opts, + const ClangdCheckOptions &CheckOpts) { std::optional LineRange; - if (!CheckFileLines.empty()) { + if (!CheckOpts.CheckFileLines.empty()) { uint32_t Begin = 0, End = std::numeric_limits::max(); - StringRef RangeStr(CheckFileLines); + StringRef RangeStr(CheckOpts.CheckFileLines); bool ParseError = RangeStr.consumeInteger(0, Begin); if (RangeStr.empty()) { End = Begin; @@ -483,17 +461,23 @@ bool check(llvm::StringRef File, const ThreadsafeFS &TFS, log("Testing on source file {0}", File); class OverrideConfigProvider : public config::Provider { + bool CheckTidyTime; std::vector getFragments(const config::Params &, config::DiagnosticCallback Diag) const override { config::Fragment F; - // If we're timing clang-tidy checks, implicitly disabling the slow ones - // is counterproductive! - if (CheckTidyTime.getNumOccurrences()) + // If we're timing clang-tidy checks, implicitly disabling the slow + // ones is counterproductive! + if (CheckTidyTime) F.Diagnostics.ClangTidy.FastCheckFilter.emplace("None"); return {std::move(F).compile(Diag)}; } - } OverrideConfig; + + public: + OverrideConfigProvider(bool CheckTidyTime) : CheckTidyTime(CheckTidyTime) {} + + } OverrideConfig{CheckOpts.CheckTidyTime.has_value()}; + auto ConfigProvider = config::Provider::combine({Opts.ConfigProvider, &OverrideConfig}); @@ -503,13 +487,13 @@ bool check(llvm::StringRef File, const ThreadsafeFS &TFS, FakeFile.empty() ? File : /*Don't turn on local configs for an arbitrary temp path.*/ "")); - Checker C(File, Opts); + Checker C(File, Opts, CheckOpts); if (!C.buildCommand(TFS) || !C.buildInvocation(TFS, Contents) || !C.buildAST()) return false; C.buildInlayHints(LineRange); C.buildSemanticHighlighting(LineRange); - if (CheckLocations) + if (CheckOpts.CheckLocations) C.testLocationFeatures(LineRange); log("All checks completed, {0} errors", C.ErrCount); diff --git a/clang-tools-extra/clangd/tool/Check.h b/clang-tools-extra/clangd/tool/Check.h new file mode 100644 index 0000000000000000000000000000000000000000..ce4e925ca088b48b94b0c3636702be7d368e781e --- /dev/null +++ b/clang-tools-extra/clangd/tool/Check.h @@ -0,0 +1,38 @@ +//===--- Check.h - clangd check fuction ------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Functions and structure definitions for Check.cpp +// +//===----------------------------------------------------------------------===// + +#include "ClangdLSPServer.h" +#include "llvm/ADT/StringRef.h" +#include + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TOOL_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TOOL_CHECK_H + +namespace clang { +namespace clangd { + +struct ClangdCheckOptions { + std::optional CheckTidyTime; + llvm::StringRef CheckFileLines; + bool CheckLocations; + bool CheckCompletion; + bool CheckWarnings; +}; + +bool check(llvm::StringRef File, const ThreadsafeFS &TFS, + const ClangdLSPServer::Options &Opts, + const ClangdCheckOptions &CheckOpts); + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_TOOL_CHECK_H diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 9fd002d0eebba5f314d0bd953210bb9275ab58b9..3b08e023236dc14c37c0c49284411710e5b5864d 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ClangdMain.h" +#include "Check.h" #include "ClangdLSPServer.h" #include "CodeComplete.h" #include "Compiler.h" @@ -63,10 +64,6 @@ namespace clang { namespace clangd { -// Implemented in Check.cpp. -bool check(const llvm::StringRef File, const ThreadsafeFS &TFS, - const ClangdLSPServer::Options &Opts); - namespace { using llvm::cl::cat; @@ -551,6 +548,34 @@ opt ProjectRoot{ }; #endif +// These will never be shown in --help, ClangdMain doesn't list the category. +// See clang-tools-extra/clangd/tool/Check.cpp for more information. +llvm::cl::opt CheckTidyTime{ + "check-tidy-time", + llvm::cl::desc("Print the overhead of checks matching this glob"), + llvm::cl::init("")}; +llvm::cl::opt CheckFileLines{ + "check-lines", + llvm::cl::desc( + "Limits the range of tokens in -check file on which " + "various features are tested. Example --check-lines=3-7 restricts " + "testing to lines 3 to 7 (inclusive) or --check-lines=5 to restrict " + "to one line. Default is testing entire file."), + llvm::cl::init("")}; +llvm::cl::opt CheckLocations{ + "check-locations", + llvm::cl::desc( + "Runs certain features (e.g. hover) at each point in the file. " + "Somewhat slow."), + llvm::cl::init(true)}; +llvm::cl::opt CheckCompletion{ + "check-completion", + llvm::cl::desc("Run code-completion at each point (slow)"), + llvm::cl::init(false)}; +llvm::cl::opt CheckWarnings{ + "check-warnings", llvm::cl::desc("Print warnings as well as errors"), + llvm::cl::init(false)}; + /// Supports a test URI scheme with relaxed constraints for lit tests. /// The path in a test URI will be combined with a platform-specific fake /// directory to form an absolute path. For example, test:///a.cpp is resolved @@ -563,7 +588,7 @@ public: using namespace llvm::sys; // Still require "/" in body to mimic file scheme, as we want lengths of an // equivalent URI in both schemes to be the same. - if (!Body.startswith("/")) + if (!Body.starts_with("/")) return error( "Expect URI body to be an absolute path starting with '/': {0}", Body); @@ -973,7 +998,17 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var return 1; } log("Entering check mode (no LSP server)"); - return check(Path, TFS, Opts) + + ClangdCheckOptions CheckOpts; + if (CheckTidyTime.getNumOccurrences()) + CheckOpts.CheckTidyTime = std::make_optional(CheckTidyTime.ValueStr); + + CheckOpts.CheckFileLines = CheckFileLines; + CheckOpts.CheckCompletion = CheckCompletion; + CheckOpts.CheckLocations = CheckLocations; + CheckOpts.CheckWarnings = CheckWarnings; + + return check(Path, TFS, Opts, CheckOpts) ? 0 : static_cast(ErrorResultCode::CheckFailed); } diff --git a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp index e5c9fc540880689cce1653583087bdbc2f2bc000..e51942462fbdf87a32aaf3d59280c482dbd96c65 100644 --- a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp @@ -132,11 +132,11 @@ TEST_F(BackgroundIndexTest, Config) { BackgroundIndex::Options Opts; Opts.ContextProvider = [](PathRef P) { Config C; - if (P.endswith("foo.cpp")) + if (P.ends_with("foo.cpp")) C.CompileFlags.Edits.push_back([](std::vector &Argv) { Argv = tooling::getInsertArgumentAdjuster("-Done=two")(Argv, ""); }); - if (P.endswith("baz.cpp")) + if (P.ends_with("baz.cpp")) C.Index.Background = Config::BackgroundPolicy::Skip; return Context::current().derive(Config::Key, std::move(C)); }; diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 692c6db3c51bedf5c6bc9e86a2a50ce232c6dbf1..6d387fec9b3851d10bda8b4164223b453242315e 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -59,7 +59,7 @@ MATCHER_P(named, Name, "") { return arg.Name == Name; } MATCHER_P(mainFileRefs, Refs, "") { return arg.MainFileRefs == Refs; } MATCHER_P(scopeRefs, Refs, "") { return arg.ScopeRefsInFile == Refs; } MATCHER_P(nameStartsWith, Prefix, "") { - return llvm::StringRef(arg.Name).startswith(Prefix); + return llvm::StringRef(arg.Name).starts_with(Prefix); } MATCHER_P(filterText, F, "") { return arg.FilterText == F; } MATCHER_P(scope, S, "") { return arg.Scope == S; } diff --git a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp index 28f0d85d332caa4f82448c1622abf4eae12cd9dd..772177b60b5eed4d02c4188d38976d47b569cb54 100644 --- a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp +++ b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp @@ -209,21 +209,6 @@ TEST(CommandMangler, ConfigEdits) { ElementsAre(_, "--driver-mode=g++", "--hello", "--", "FOO.CC")); } -TEST(CommandMangler, ExpandedResponseFiles) { - SmallString<1024> Path; - int FD; - ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("args", "", FD, Path)); - llvm::raw_fd_ostream OutStream(FD, true); - OutStream << "-Wall"; - OutStream.close(); - - auto Mangler = CommandMangler::forTests(); - tooling::CompileCommand Cmd; - Cmd.CommandLine = {"clang", ("@" + Path).str(), "foo.cc"}; - Mangler(Cmd, "foo.cc"); - EXPECT_THAT(Cmd.CommandLine, ElementsAre(_, "-Wall", "--", "foo.cc")); -} - static std::string strip(llvm::StringRef Arg, llvm::StringRef Argv) { llvm::SmallVector Parts; llvm::SplitString(Argv, Parts); diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index a52b647b0029b4facb59f2eac7587bdadc69ea4a..37643e5afa2304d2aa7673fc5a4aa8a1ccf40f97 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -1935,7 +1935,7 @@ $fix[[ $diag[[#include "unused.h"]] Cfg.Diagnostics.UnusedIncludes = Config::IncludesPolicy::Strict; // Set filtering. Cfg.Diagnostics.Includes.IgnoreHeader.emplace_back( - [](llvm::StringRef Header) { return Header.endswith("ignore.h"); }); + [](llvm::StringRef Header) { return Header.ends_with("ignore.h"); }); WithContextValue WithCfg(Config::Key, std::move(Cfg)); auto AST = TU.build(); EXPECT_THAT( diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp index 38bf66a1e25eb57025d765eddd0d518c593e0e0b..a2ffdefe1bbcb2d7b1ef5fff183a5fef533a3284 100644 --- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp @@ -163,6 +163,21 @@ TEST_F(OverlayCDBTest, Adjustments) { "-DFallback", "-DAdjust_baz.cc")); } +TEST_F(OverlayCDBTest, ExpandedResponseFiles) { + SmallString<1024> Path; + int FD; + ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("args", "", FD, Path)); + llvm::raw_fd_ostream OutStream(FD, true); + OutStream << "-Wall"; + OutStream.close(); + + OverlayCDB CDB(Base.get(), {"-DFallback"}); + auto Override = cmd(testPath("foo.cc"), ("@" + Path).str()); + CDB.setCompileCommand(testPath("foo.cc"), Override); + EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine, + Contains("-Wall")); +} + TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) { const char *const CDBOuter = R"cdb( @@ -228,14 +243,14 @@ TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) { DirectoryBasedGlobalCompilationDatabase::Options Opts(FS); Opts.ContextProvider = [&](llvm::StringRef Path) { Config Cfg; - if (Path.endswith("a.cc")) { + if (Path.ends_with("a.cc")) { // a.cc uses another directory's CDB, so it won't be discovered. Cfg.CompileFlags.CDBSearch.Policy = Config::CDBSearchSpec::FixedDir; Cfg.CompileFlags.CDBSearch.FixedCDBPath = testPath("foo"); - } else if (Path.endswith("gen.cc")) { + } else if (Path.ends_with("gen.cc")) { // gen.cc has CDB search disabled, so it won't be discovered. Cfg.CompileFlags.CDBSearch.Policy = Config::CDBSearchSpec::NoCDBSearch; - } else if (Path.endswith("gen2.cc")) { + } else if (Path.ends_with("gen2.cc")) { // gen2.cc explicitly lists this directory, so it will be discovered. Cfg.CompileFlags.CDBSearch.Policy = Config::CDBSearchSpec::FixedDir; Cfg.CompileFlags.CDBSearch.FixedCDBPath = testRoot(); @@ -421,6 +436,45 @@ TEST_F(OverlayCDBTest, GetProjectInfo) { EXPECT_EQ(DB.getProjectInfo(File)->SourceRoot, testRoot()); EXPECT_EQ(DB.getProjectInfo(Header)->SourceRoot, testRoot()); } + +TEST(GlobalCompilationDatabaseTest, InferenceWithResponseFile) { + MockFS FS; + auto Command = [&](llvm::StringRef Relative) { + DirectoryBasedGlobalCompilationDatabase::Options Opts(FS); + return DirectoryBasedGlobalCompilationDatabase(Opts) + .getCompileCommand(testPath(Relative)) + .value_or(tooling::CompileCommand()) + .CommandLine; + }; + EXPECT_THAT(Command("foo.cc"), IsEmpty()); + + // Have to use real FS for response file. + SmallString<1024> Path; + int FD; + ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("args", "", FD, Path)); + llvm::raw_fd_ostream OutStream(FD, true); + OutStream << "-DXYZZY"; + OutStream.close(); + + const char *const CDB = + R"cdb( + [ + { + "file": "{0}/foo.cc", + "command": "clang @{1} {0}/foo.cc", + "directory": "{0}", + } + ] + )cdb"; + FS.Files[testPath("compile_commands.json")] = + llvm::formatv(CDB, llvm::sys::path::convert_to_slash(testRoot()), + llvm::sys::path::convert_to_slash(Path)); + + // File from CDB. + EXPECT_THAT(Command("foo.cc"), Contains("-DXYZZY")); + // File not in CDB, use inference. + EXPECT_THAT(Command("foo.h"), Contains("-DXYZZY")); +} } // namespace // Friend test has access to internals. diff --git a/clang-tools-extra/clangd/unittests/IndexActionTests.cpp b/clang-tools-extra/clangd/unittests/IndexActionTests.cpp index fad751bd0f7dc220d8ffb4434b7eefec6b1d2762..2a9b8c9a1d3383b8dbed259686eba72dfe60e4dc 100644 --- a/clang-tools-extra/clangd/unittests/IndexActionTests.cpp +++ b/clang-tools-extra/clangd/unittests/IndexActionTests.cpp @@ -280,7 +280,7 @@ TEST_F(IndexActionTest, SkipFiles) { auto unskippable2() { return S(); } )cpp"); Opts.FileFilter = [](const SourceManager &SM, FileID F) { - return !SM.getFileEntryRefForID(F)->getName().endswith("bad.h"); + return !SM.getFileEntryRefForID(F)->getName().ends_with("bad.h"); }; IndexFileIn IndexFile = runIndexingAction(MainFilePath, {"-std=c++14"}); EXPECT_THAT(*IndexFile.Symbols, @@ -333,7 +333,7 @@ TEST_F(IndexActionTest, SymbolFromCC) { void foo(); )cpp"); Opts.FileFilter = [](const SourceManager &SM, FileID F) { - return !SM.getFileEntryRefForID(F)->getName().endswith("main.h"); + return !SM.getFileEntryRefForID(F)->getName().ends_with("main.h"); }; IndexFileIn IndexFile = runIndexingAction(MainFilePath, {"-std=c++14"}); EXPECT_THAT(*IndexFile.Symbols, @@ -341,6 +341,36 @@ TEST_F(IndexActionTest, SymbolFromCC) { hasName("foo"), includeHeader(URI::create(testPath("main.h")).toString())))); } + +TEST_F(IndexActionTest, IncludeHeaderForwardDecls) { + std::string MainFilePath = testPath("main.cpp"); + addFile(MainFilePath, R"cpp( +#include "fwd.h" +#include "full.h" + )cpp"); + addFile(testPath("fwd.h"), R"cpp( +#ifndef _FWD_H_ +#define _FWD_H_ +struct Foo; +#endif + )cpp"); + addFile(testPath("full.h"), R"cpp( +#ifndef _FULL_H_ +#define _FULL_H_ +struct Foo {}; + +// This decl is important, as otherwise we detect control macro for the file, +// before handling definition of Foo. +void other(); +#endif + )cpp"); + IndexFileIn IndexFile = runIndexingAction(MainFilePath); + EXPECT_THAT(*IndexFile.Symbols, + testing::Contains(AllOf( + hasName("Foo"), + includeHeader(URI::create(testPath("full.h")).toString())))) + << *IndexFile.Symbols->begin(); +} } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 6e91053632e00bfac1800f2771c2cbee097c53ae..0fff0dfca6c9b8f21a459a4ec63b4821555c21a0 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -58,8 +58,8 @@ struct ExpectedHint { MATCHER_P2(HintMatcher, Expected, Code, llvm::to_string(Expected)) { llvm::StringRef ExpectedView(Expected.Label); if (arg.label != ExpectedView.trim(" ") || - arg.paddingLeft != ExpectedView.startswith(" ") || - arg.paddingRight != ExpectedView.endswith(" ")) { + arg.paddingLeft != ExpectedView.starts_with(" ") || + arg.paddingRight != ExpectedView.ends_with(" ")) { *result_listener << "label is '" << arg.label << "'"; return false; } @@ -2205,6 +2205,19 @@ TEST(BlockEndHints, Macro) { ExpectedHint{" // struct S1", "S1"}); } +TEST(BlockEndHints, PointerToMemberFunction) { + // Do not crash trying to summarize `a->*p`. + assertBlockEndHints(R"cpp( + class A {}; + using Predicate = bool(A::*)(); + void foo(A* a, Predicate p) { + if ((a->*p)()) { + $ptrmem[[}]] + } // suppress + )cpp", + ExpectedHint{" // if", "ptrmem"}); +} + // FIXME: Low-hanging fruit where we could omit a type hint: // - auto x = TypeName(...); // - auto x = (TypeName) (...); diff --git a/clang-tools-extra/clangd/unittests/InsertionPointTests.cpp b/clang-tools-extra/clangd/unittests/InsertionPointTests.cpp index 62c06bb863772f6a5fcb7f98582b6020019d05ef..3d5365a099f0ad586dd6be94fd62781caefafac4 100644 --- a/clang-tools-extra/clangd/unittests/InsertionPointTests.cpp +++ b/clang-tools-extra/clangd/unittests/InsertionPointTests.cpp @@ -38,7 +38,7 @@ TEST(InsertionPointTests, Generic) { [&](llvm::StringLiteral S) -> std::function { return [S](const Decl *D) { if (const auto *ND = llvm::dyn_cast(D)) - return llvm::StringRef(ND->getNameAsString()).startswith(S); + return llvm::StringRef(ND->getNameAsString()).starts_with(S); return false; }; }; diff --git a/clang-tools-extra/clangd/unittests/StdLibTests.cpp b/clang-tools-extra/clangd/unittests/StdLibTests.cpp index ef47141bade153f8ffb6d574a5bfac87fe7038e3..a39d34ea33811ae4171576b7c2ca823de53f6f87 100644 --- a/clang-tools-extra/clangd/unittests/StdLibTests.cpp +++ b/clang-tools-extra/clangd/unittests/StdLibTests.cpp @@ -126,7 +126,7 @@ TEST(StdLibTests, StdLibSet) { MATCHER_P(StdlibSymbol, Name, "") { return arg.Name == Name && arg.Includes.size() == 1 && - llvm::StringRef(arg.Includes.front().Header).startswith("<"); + llvm::StringRef(arg.Includes.front().Header).starts_with("<"); } TEST(StdLibTests, EndToEnd) { diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp index f12441061c1983654585ebeb33380d52cdf13515..9cdc57ec01f32761e7ba478573a27561b10267ef 100644 --- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp @@ -1917,14 +1917,14 @@ TEST_F(SymbolCollectorTest, UndefOfModuleMacro) { #undef X )cpp"; TU.AdditionalFiles["foo.h"] = "#define X 1"; - TU.AdditionalFiles["module.map"] = R"cpp( + TU.AdditionalFiles["module.modulemap"] = R"cpp( module foo { header "foo.h" export * } )cpp"; TU.ExtraArgs.push_back("-fmodules"); - TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("module.map")); + TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("module.modulemap")); TU.OverlayRealFileSystemForModules = true; TU.build(); diff --git a/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp index 51071d89a66e51bbb5a1469db9e5370ca33c43fc..81e65ede00781acb51584f3568f82ffa08602b06 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp @@ -43,7 +43,7 @@ llvm::StringRef unwrap(Context Ctx, llvm::StringRef Outer) { auto Wrapping = wrapping(Ctx); // Unwrap only if the code matches the expected wrapping. // Don't allow the begin/end wrapping to overlap! - if (Outer.startswith(Wrapping.first) && Outer.endswith(Wrapping.second) && + if (Outer.starts_with(Wrapping.first) && Outer.ends_with(Wrapping.second) && Outer.size() >= Wrapping.first.size() + Wrapping.second.size()) return Outer.drop_front(Wrapping.first.size()) .drop_back(Wrapping.second.size()); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6d91748e4cef18c7329b2ded0e68125500f44847..571808a51596a885c0be06b381a42b00b2a66923 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -119,15 +119,22 @@ Improvements to clang-tidy - Improved `--dump-config` to print check options in alphabetical order. -- Improved :program:`clang-tidy-diff.py` script. It now returns exit code `1` - if any :program:`clang-tidy` subprocess exits with a non-zero code or if - exporting fixes fails. It now accepts a directory as a value for - `-export-fixes` to export individual yaml files for each compilation unit. +- Improved :program:`clang-tidy-diff.py` script. + * Return exit code `1` if any :program:`clang-tidy` subprocess exits with + a non-zero code or if exporting fixes fails. + + * Accept a directory as a value for `-export-fixes` to export individual + yaml files for each compilation unit. + + * Introduce a `-config-file` option that forwards a configuration file to + :program:`clang-tidy`. Corresponds to the `--config-file` option in + :program:`clang-tidy`. - Improved :program:`run-clang-tidy.py` script. It now accepts a directory as a value for `-export-fixes` to export individual yaml files for each compilation unit. + New checks ^^^^^^^^^^ @@ -168,6 +175,11 @@ New checks extracted from an optional-like type and then used to create a new instance of the same optional-like type. +- New :doc:`bugprone-unused-local-non-trivial-variable + ` check. + + Warns when a local non trivial variable is unused within a function. + - New :doc:`cppcoreguidelines-no-suspend-with-lock ` check. @@ -396,7 +408,8 @@ Changes in existing checks - Improved :doc:`modernize-use-using ` check to fix function pointer and - forward declared ``typedef`` correctly. + forward declared ``typedef`` correctly. Added option `IgnoreExternC` to ignore ``typedef`` + declaration in ``extern "C"`` scope. - Improved :doc:`performance-faster-string-find ` check to properly escape @@ -441,7 +454,10 @@ Changes in existing checks has been enhanced, particularly within complex types like function pointers and cases where style checks were omitted when functions started with macros. Added support for C++20 ``concept`` declarations. ``Camel_Snake_Case`` and - ``camel_Snake_Case`` now detect more invalid identifier names. + ``camel_Snake_Case`` now detect more invalid identifier names. Fields in + anonymous records (i.e. anonymous structs and unions) now can be checked with + the naming rules associated with their enclosing scopes rather than the naming + rules of public struct/union members. - Improved :doc:`readability-implicit-bool-conversion ` check to take @@ -449,10 +465,18 @@ Changes in existing checks `AllowPointerConditions` options. It also now provides more consistent suggestions when parentheses are added to the return value. +- Improved :doc:`readability-misleading-indentation + ` check to ignore + false-positives for line started with empty macro. + - Improved :doc:`readability-non-const-parameter ` check to ignore false-positives in initializer list of record. +- Improved :doc:`readability-simplify-subscript-expr + ` check by extending + the default value of the `Types` option to include ``std::span``. + - Improved :doc:`readability-static-accessed-through-instance ` check to identify calls to static member functions with out-of-class inline definitions. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-local-non-trivial-variable.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-local-non-trivial-variable.rst new file mode 100644 index 0000000000000000000000000000000000000000..7531f19f3ebc15bcf35a43bc71170c69c6bcaed3 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-local-non-trivial-variable.rst @@ -0,0 +1,55 @@ +.. title:: clang-tidy - bugprone-unused-local-non-trivial-variable + +bugprone-unused-local-non-trivial-variable +========================================== + +Warns when a local non trivial variable is unused within a function. +The following types of variables are excluded from this check: + +* trivial and trivially copyable +* references and pointers +* exception variables in catch clauses +* static or thread local +* structured bindings + +This check can be configured to warn on all non-trivial variables by setting +`IncludeTypes` to `.*`, and excluding specific types using `ExcludeTypes`. + +In the this example, `my_lock` would generate a warning that it is unused. + +.. code-block:: c++ + + std::mutex my_lock; + // my_lock local variable is never used + +In the next example, `future2` would generate a warning that it is unused. + +.. code-block:: c++ + + std::future future1; + std::future future2; + // ... + MyObject foo = future1.get(); + // future2 is not used. + +Options +------- + +.. option:: IncludeTypes + + Semicolon-separated list of regular expressions matching types of variables + to check. By default the following types are checked: + + * `::std::.*mutex` + * `::std::future` + * `::std::basic_string` + * `::std::basic_regex` + * `::std::basic_istringstream` + * `::std::basic_stringstream` + * `::std::bitset` + * `::std::filesystem::path` + +.. option:: ExcludeTypes + + A semicolon-separated list of regular expressions matching types that are + excluded from the `IncludeTypes` matches. By default it is an empty list. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.core.EnumCastOutOfRange.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.core.EnumCastOutOfRange.rst new file mode 100644 index 0000000000000000000000000000000000000000..99dd1adf38f6b9c746f008064b1d5b76643499f2 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.core.EnumCastOutOfRange.rst @@ -0,0 +1,13 @@ +.. title:: clang-tidy - clang-analyzer-optin.core.EnumCastOutOfRange +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#optin-core-enumcastoutofrange + +clang-analyzer-optin.core.EnumCastOutOfRange +============================================ + +Check integer to enumeration casts for out of range values. + +The `clang-analyzer-optin.core.EnumCastOutOfRange` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.cert.env.InvalidPtr.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.cert.env.InvalidPtr.rst new file mode 100644 index 0000000000000000000000000000000000000000..8986fa0e684f582742992c619fe2c15c0d0f5580 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.cert.env.InvalidPtr.rst @@ -0,0 +1,13 @@ +.. title:: clang-tidy - clang-analyzer-security.cert.env.InvalidPtr +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#security-cert-env-invalidptr + +clang-analyzer-security.cert.env.InvalidPtr +=========================================== + +Finds usages of possibly invalidated pointers. + +The `clang-analyzer-security.cert.env.InvalidPtr` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.Errno.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.Errno.rst new file mode 100644 index 0000000000000000000000000000000000000000..67a2d05811dc159e016dde2e6f6fa7f635aa7a8e --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.Errno.rst @@ -0,0 +1,13 @@ +.. title:: clang-tidy - clang-analyzer-unix.Errno +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#unix-errno + +clang-analyzer-unix.Errno +========================= + +Check for improper use of 'errno'. + +The `clang-analyzer-unix.Errno` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.StdCLibraryFunctions.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.StdCLibraryFunctions.rst new file mode 100644 index 0000000000000000000000000000000000000000..17906732c86f70bdffaa7c890ea80fa251b36c80 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.StdCLibraryFunctions.rst @@ -0,0 +1,14 @@ +.. title:: clang-tidy - clang-analyzer-unix.StdCLibraryFunctions +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#unix-stdclibraryfunctions + +clang-analyzer-unix.StdCLibraryFunctions +======================================== + +Check for invalid arguments of C standard library functions, and apply relations +between arguments and return value. + +The `clang-analyzer-unix.StdCLibraryFunctions` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 31f0e090db1d7de7d39a540e50a0131f96b9db91..b36bf7d497b9dd9793045d71af954182bb1e01d6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -149,6 +149,7 @@ Clang-Tidy Checks :doc:`bugprone-unhandled-self-assignment `, :doc:`bugprone-unique-ptr-array-mismatch `, "Yes" :doc:`bugprone-unsafe-functions `, + :doc:`bugprone-unused-local-non-trivial-variable `, :doc:`bugprone-unused-raii `, "Yes" :doc:`bugprone-unused-return-value `, :doc:`bugprone-use-after-move `, @@ -439,6 +440,7 @@ Clang-Tidy Checks :doc:`clang-analyzer-nullability.NullableDereferenced `, `Clang Static Analyzer nullability.NullableDereferenced `_, :doc:`clang-analyzer-nullability.NullablePassedToNonnull `, `Clang Static Analyzer nullability.NullablePassedToNonnull `_, :doc:`clang-analyzer-nullability.NullableReturnedFromNonnull `, `Clang Static Analyzer nullability.NullableReturnedFromNonnull `_, + :doc:`clang-analyzer-optin.core.EnumCastOutOfRange `, `Clang Static Analyzer optin.core.EnumCastOutOfRange `_, :doc:`clang-analyzer-optin.cplusplus.UninitializedObject `, `Clang Static Analyzer optin.cplusplus.UninitializedObject `_, :doc:`clang-analyzer-optin.cplusplus.VirtualCall `, `Clang Static Analyzer optin.cplusplus.VirtualCall `_, :doc:`clang-analyzer-optin.mpi.MPI-Checker `, `Clang Static Analyzer optin.mpi.MPI-Checker `_, @@ -478,6 +480,7 @@ Clang-Tidy Checks :doc:`clang-analyzer-osx.coreFoundation.containers.OutOfBounds `, `Clang Static Analyzer osx.coreFoundation.containers.OutOfBounds `_, :doc:`clang-analyzer-osx.coreFoundation.containers.PointerSizedValues `, `Clang Static Analyzer osx.coreFoundation.containers.PointerSizedValues `_, :doc:`clang-analyzer-security.FloatLoopCounter `, `Clang Static Analyzer security.FloatLoopCounter `_, + :doc:`clang-analyzer-security.cert.env.InvalidPtr `, `Clang Static Analyzer security.cert.env.InvalidPtr `_, :doc:`clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling `, `Clang Static Analyzer security.insecureAPI.DeprecatedOrUnsafeBufferHandling `_, :doc:`clang-analyzer-security.insecureAPI.UncheckedReturn `, `Clang Static Analyzer security.insecureAPI.UncheckedReturn `_, :doc:`clang-analyzer-security.insecureAPI.bcmp `, `Clang Static Analyzer security.insecureAPI.bcmp `_, @@ -492,9 +495,11 @@ Clang-Tidy Checks :doc:`clang-analyzer-security.insecureAPI.strcpy `, `Clang Static Analyzer security.insecureAPI.strcpy `_, :doc:`clang-analyzer-security.insecureAPI.vfork `, `Clang Static Analyzer security.insecureAPI.vfork `_, :doc:`clang-analyzer-unix.API `, `Clang Static Analyzer unix.API `_, + :doc:`clang-analyzer-unix.Errno `, `Clang Static Analyzer unix.Errno `_, :doc:`clang-analyzer-unix.Malloc `, `Clang Static Analyzer unix.Malloc `_, :doc:`clang-analyzer-unix.MallocSizeof `, `Clang Static Analyzer unix.MallocSizeof `_, :doc:`clang-analyzer-unix.MismatchedDeallocator `, `Clang Static Analyzer unix.MismatchedDeallocator `_, + :doc:`clang-analyzer-unix.StdCLibraryFunctions `, `Clang Static Analyzer unix.StdCLibraryFunctions `_, :doc:`clang-analyzer-unix.Vfork `, `Clang Static Analyzer unix.Vfork `_, :doc:`clang-analyzer-unix.cstring.BadSizeArg `, `Clang Static Analyzer unix.cstring.BadSizeArg `_, :doc:`clang-analyzer-unix.cstring.NullArg `, `Clang Static Analyzer unix.cstring.NullArg `_, diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-using.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-using.rst index eeddaf8d8d65abee28c7aa3e902881a1b0845161..32272a07994c229cd75701e8485c4baf13f2cd58 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-using.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-using.rst @@ -28,6 +28,14 @@ After: using R_t = struct { int a; }; using R_p = R_t*; +The checker ignores `typedef` within `extern "C" { ... }` blocks. + +.. code-block:: c++ + + extern "C" { + typedef int InExternC; // Left intact. + } + This check requires using C++11 or higher to run. Options @@ -37,3 +45,8 @@ Options If set to `true`, the check will not give warnings inside macros. Default is `true`. + +.. option:: IgnoreExternC + + If set to `true`, the check will not give warning inside `extern "C"`scope. + Default is `false` \ No newline at end of file diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst index e36bbee394f17aef3cb98d6e9030bd7994571361..2affb55cfa9ad7393491cf4b7ba21bdf51b185c2 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst @@ -42,6 +42,7 @@ The following options are described below: - :option:`AbstractClassCase`, :option:`AbstractClassPrefix`, :option:`AbstractClassSuffix`, :option:`AbstractClassIgnoredRegexp`, :option:`AbstractClassHungarianPrefix` - :option:`AggressiveDependentMemberLookup` + - :option:`CheckAnonFieldInParent` - :option:`ClassCase`, :option:`ClassPrefix`, :option:`ClassSuffix`, :option:`ClassIgnoredRegexp`, :option:`ClassHungarianPrefix` - :option:`ClassConstantCase`, :option:`ClassConstantPrefix`, :option:`ClassConstantSuffix`, :option:`ClassConstantIgnoredRegexp`, :option:`ClassConstantHungarianPrefix` - :option:`ClassMemberCase`, :option:`ClassMemberPrefix`, :option:`ClassMemberSuffix`, :option:`ClassMemberIgnoredRegexp`, :option:`ClassMemberHungarianPrefix` @@ -207,6 +208,32 @@ After if AggressiveDependentMemberLookup is `true`: } }; +.. option:: CheckAnonFieldInParent + + When set to `true`, fields in anonymous records (i.e. anonymous + unions and structs) will be treated as names in the enclosing scope + rather than public members of the anonymous record for the purpose + of name checking. + +For example: + +.. code-block:: c++ + + class Foo { + private: + union { + int iv_; + float fv_; + }; + }; + +If :option:`CheckAnonFieldInParent` is `false`, you may get warnings +that ``iv_`` and ``fv_`` are not coherent to public member names, because +``iv_`` and ``fv_`` are public members of the anonymous union. When +:option:`CheckAnonFieldInParent` is `true`, ``iv_`` and ``fv_`` will be +treated as private data members of ``Foo`` for the purpose of name checking +and thus no warnings will be emitted. + .. option:: ClassCase When defined, the check will ensure class names conform to the diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/simplify-subscript-expr.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/simplify-subscript-expr.rst index f3f44bedcf74c5c10cb528d9bca7740ad7eed3e1..4b7d7f2ddcf4171d29b3896128e144893f72ad04 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/simplify-subscript-expr.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/simplify-subscript-expr.rst @@ -20,4 +20,4 @@ Options .. option:: Types The list of type(s) that triggers this check. Default is - `::std::basic_string;::std::basic_string_view;::std::vector;::std::array` + `::std::basic_string;::std::basic_string_view;::std::vector;::std::array;::std::span` diff --git a/clang-tools-extra/docs/modularize.rst b/clang-tools-extra/docs/modularize.rst index 9dde467ec30847dcd748a60a0ee88d6090f86df1..64ca8c99d4e8efa6752b95e5b903f956c43e9c82 100644 --- a/clang-tools-extra/docs/modularize.rst +++ b/clang-tools-extra/docs/modularize.rst @@ -20,7 +20,7 @@ map. :program:`modularize` also has an assistant mode option for generating a module map file based on the provided header list. The generated file is a functional module map that can be used as a starting point for a -module.map file. +module.modulemap file. Getting Started =============== diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp index 450c4c796c141567f8620fe03b631e7d0160b91d..f1cd72f877ca21bfa7eeab6b7278383350350369 100644 --- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp +++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp @@ -126,7 +126,7 @@ analyze(llvm::ArrayRef ASTRoots, // Since most private -> public mappings happen in a verbatim way, we // check textually here. This might go wrong in presence of symlinks or // header mappings. But that's not different than rest of the places. - if (MainFile->tryGetRealPathName().endswith(PHeader)) + if (MainFile->tryGetRealPathName().ends_with(PHeader)) continue; } } diff --git a/clang-tools-extra/include-cleaner/lib/Record.cpp b/clang-tools-extra/include-cleaner/lib/Record.cpp index 6e00ff93a7fe2fae384026e9db8d05bcad73a7c3..bd726cff12a97d915da4b8026fd27acfccf332ea 100644 --- a/clang-tools-extra/include-cleaner/lib/Record.cpp +++ b/clang-tools-extra/include-cleaner/lib/Record.cpp @@ -277,7 +277,7 @@ public: int CommentLine = SM.getLineNumber(CommentFID, CommentOffset); if (InMainFile) { - if (Pragma->startswith("keep")) { + if (Pragma->starts_with("keep")) { KeepStack.push_back({CommentLine, false}); } else if (Pragma->starts_with("begin_keep")) { KeepStack.push_back({CommentLine, true}); @@ -300,9 +300,10 @@ public: StringRef PublicHeader; if (Pragma->consume_front(", include ")) { // We always insert using the spelling from the pragma. - PublicHeader = save(Pragma->startswith("<") || Pragma->startswith("\"") - ? (*Pragma) - : ("\"" + *Pragma + "\"").str()); + PublicHeader = + save(Pragma->starts_with("<") || Pragma->starts_with("\"") + ? (*Pragma) + : ("\"" + *Pragma + "\"").str()); } Out->IWYUPublic.insert({CommentUID, PublicHeader}); return false; @@ -313,11 +314,11 @@ public: } auto Filename = FE->getName(); // Record export pragma. - if (Pragma->startswith("export")) { + if (Pragma->starts_with("export")) { ExportStack.push_back({CommentLine, CommentFID, save(Filename), false}); - } else if (Pragma->startswith("begin_exports")) { + } else if (Pragma->starts_with("begin_exports")) { ExportStack.push_back({CommentLine, CommentFID, save(Filename), true}); - } else if (Pragma->startswith("end_exports")) { + } else if (Pragma->starts_with("end_exports")) { // FIXME: be robust on unmatching cases. We should only pop the stack if // the begin_exports and end_exports is in the same file. if (!ExportStack.empty()) { diff --git a/clang-tools-extra/include-cleaner/test/Inputs/modules/module.map b/clang-tools-extra/include-cleaner/test/Inputs/modules/module.modulemap similarity index 100% rename from clang-tools-extra/include-cleaner/test/Inputs/modules/module.map rename to clang-tools-extra/include-cleaner/test/Inputs/modules/module.modulemap diff --git a/clang-tools-extra/modularize/CoverageChecker.cpp b/clang-tools-extra/modularize/CoverageChecker.cpp index d8445053872bf22fbfb0fe73f7b205ce58fd81d7..1e8b0aa37ca309931c9d2c70433ffb22bc6018aa 100644 --- a/clang-tools-extra/modularize/CoverageChecker.cpp +++ b/clang-tools-extra/modularize/CoverageChecker.cpp @@ -302,7 +302,7 @@ void CoverageChecker::collectUmbrellaHeaderHeader(StringRef HeaderName) { sys::fs::current_path(PathBuf); // HeaderName will have an absolute path, so if it's the module map // directory, we remove it, also skipping trailing separator. - if (HeaderName.startswith(PathBuf)) + if (HeaderName.starts_with(PathBuf)) HeaderName = HeaderName.substr(PathBuf.size() + 1); // Save header name. ModuleMapHeadersSet.insert(ModularizeUtilities::getCanonicalPath(HeaderName)); @@ -356,8 +356,8 @@ bool CoverageChecker::collectFileSystemHeaders(StringRef IncludePath) { sys::path::append(Directory, IncludePath); if (Directory.size() == 0) Directory = "."; - if (IncludePath.startswith("/") || IncludePath.startswith("\\") || - ((IncludePath.size() >= 2) && (IncludePath[1] == ':'))) { + if (IncludePath.starts_with("/") || IncludePath.starts_with("\\") || + ((IncludePath.size() >= 2) && (IncludePath[1] == ':'))) { llvm::errs() << "error: Include path \"" << IncludePath << "\" is not relative to the module map file.\n"; return false; diff --git a/clang-tools-extra/modularize/Modularize.cpp b/clang-tools-extra/modularize/Modularize.cpp index daa9c048279e03fed32e986c7c4869ad3d243094..f3e7dfc20b027d08d39fcc1f64d61cbea019b5e2 100644 --- a/clang-tools-extra/modularize/Modularize.cpp +++ b/clang-tools-extra/modularize/Modularize.cpp @@ -51,20 +51,20 @@ // to the header list file directory. Use -prefix to specify a // different directory. // -module-map-path=(module map) -// Skip the checks, and instead act as a module.map generation +// Skip the checks, and instead act as a module.modulemap generation // assistant, generating a module map file based on the header list. // An optional "-root-module=(rootName)" argument can specify a root -// module to be created in the generated module.map file. Note that -// you will likely need to edit this file to suit the needs of your -// headers. +// module to be created in the generated module.modulemap file. Note +// that you will likely need to edit this file to suit the needs of +// your headers. // -problem-files-list=(problem files list file name) // For use only with module map assistant. Input list of files that // have problems with respect to modules. These will still be // included in the generated module map, but will be marked as // "excluded" headers. // -root-module=(root module name) -// Specifies a root module to be created in the generated module.map -// file. +// Specifies a root module to be created in the generated +// module.modulemap file. // -block-check-header-list-only // Only warn if #include directives are inside extern or namespace // blocks if the included header is in the header list. diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp index 089f52f52ec4d341826294df72da43eafae0637a..25de9c9dd05ac9cae44e3336395fcf6092155e08 100644 --- a/clang-tools-extra/modularize/ModularizeUtilities.cpp +++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp @@ -75,12 +75,11 @@ std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() { for (auto I = InputFilePaths.begin(), E = InputFilePaths.end(); I != E; ++I) { llvm::StringRef InputPath = *I; // If it's a module map. - if (InputPath.endswith(".modulemap")) { + if (InputPath.ends_with(".modulemap")) { // Load the module map. if (std::error_code EC = loadModuleMap(InputPath)) return EC; - } - else { + } else { // Else we assume it's a header list and load it. if (std::error_code EC = loadSingleHeaderListsAndDependencies(InputPath)) { errs() << "modularize: error: Unable to get header list '" << InputPath @@ -103,10 +102,10 @@ std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() { // Do coverage checks. // For each loaded module map, do header coverage check. -// Starting from the directory of the module.map file, +// Starting from the directory of the module.modulemap file, // Find all header files, optionally looking only at files // covered by the include path options, and compare against -// the headers referenced by the module.map file. +// the headers referenced by the module.modulemap file. // Display warnings for unaccounted-for header files. // Returns 0 if there were no errors or warnings, 1 if there // were warnings, 2 if any other problem, such as a bad @@ -276,7 +275,7 @@ std::error_code ModularizeUtilities::loadModuleMap( StringRef DirName(Dir.getName()); if (llvm::sys::path::filename(DirName) == "Modules") { DirName = llvm::sys::path::parent_path(DirName); - if (DirName.endswith(".framework")) { + if (DirName.ends_with(".framework")) { auto FrameworkDirOrErr = FileMgr->getDirectoryRef(DirName); if (!FrameworkDirOrErr) { // This can happen if there's a race between the above check and the @@ -444,7 +443,7 @@ static std::string replaceDotDot(StringRef Path) { llvm::sys::path::append(Buffer, *B); ++B; } - if (Path.endswith("/") || Path.endswith("\\")) + if (Path.ends_with("/") || Path.ends_with("\\")) Buffer.append(1, Path.back()); return Buffer.c_str(); } @@ -457,7 +456,7 @@ std::string ModularizeUtilities::getCanonicalPath(StringRef FilePath) { std::string Tmp(replaceDotDot(FilePath)); std::replace(Tmp.begin(), Tmp.end(), '\\', '/'); StringRef Tmp2(Tmp); - if (Tmp2.startswith("./")) + if (Tmp2.starts_with("./")) Tmp = std::string(Tmp2.substr(2)); return Tmp; } diff --git a/clang-tools-extra/modularize/ModularizeUtilities.h b/clang-tools-extra/modularize/ModularizeUtilities.h index 6da15e42f1f1ea67ecba84e5acd78e945486b6a7..64675022dad76e0706bdbcfcfc3037925d7959c3 100644 --- a/clang-tools-extra/modularize/ModularizeUtilities.h +++ b/clang-tools-extra/modularize/ModularizeUtilities.h @@ -89,10 +89,10 @@ public: /// Do coverage checks. /// For each loaded module map, do header coverage check. - /// Starting from the directory of the module.map file, + /// Starting from the directory of the module.modulemap file, /// Find all header files, optionally looking only at files /// covered by the include path options, and compare against - /// the headers referenced by the module.map file. + /// the headers referenced by the module.modulemap file. /// Display warnings for unaccounted-for header files. /// \param IncludePaths The include paths to check for files. /// (Note that other directories above these paths are ignored. diff --git a/clang-tools-extra/modularize/PreprocessorTracker.cpp b/clang-tools-extra/modularize/PreprocessorTracker.cpp index 335195c6b199e7690ed1fa8c061507631b6d9b83..7557fb177ceb48a24b8bc10960daba160c19e31e 100644 --- a/clang-tools-extra/modularize/PreprocessorTracker.cpp +++ b/clang-tools-extra/modularize/PreprocessorTracker.cpp @@ -883,7 +883,7 @@ public: // Handle entering a header source file. void handleHeaderEntry(clang::Preprocessor &PP, llvm::StringRef HeaderPath) { // Ignore and to reduce message clutter. - if (HeaderPath.startswith("<")) + if (HeaderPath.starts_with("<")) return; HeaderHandle H = addHeader(HeaderPath); if (H != getCurrentHeaderHandle()) @@ -896,7 +896,7 @@ public: // Handle exiting a header source file. void handleHeaderExit(llvm::StringRef HeaderPath) { // Ignore and to reduce message clutter. - if (HeaderPath.startswith("<")) + if (HeaderPath.starts_with("<")) return; HeaderHandle H = findHeaderHandle(HeaderPath); HeaderHandle TH; diff --git a/clang-tools-extra/pseudo/lib/cxx/CXX.cpp b/clang-tools-extra/pseudo/lib/cxx/CXX.cpp index 46d837aec44ad3eac8806e5ae661d58f3a9607b7..4188dab31d3a91284e7dba646fab065612617ff2 100644 --- a/clang-tools-extra/pseudo/lib/cxx/CXX.cpp +++ b/clang-tools-extra/pseudo/lib/cxx/CXX.cpp @@ -28,9 +28,9 @@ static const char *CXXBNF = // User-defined string literals look like `""suffix`. bool isStringUserDefined(const Token &Tok) { - return !Tok.text().endswith("\""); + return !Tok.text().ends_with("\""); } -bool isCharUserDefined(const Token &Tok) { return !Tok.text().endswith("'"); } +bool isCharUserDefined(const Token &Tok) { return !Tok.text().ends_with("'"); } // Combinable flags describing numbers. // Clang has just one numeric_token kind, the grammar has 4. diff --git a/clang-tools-extra/pseudo/lib/grammar/GrammarBNF.cpp b/clang-tools-extra/pseudo/lib/grammar/GrammarBNF.cpp index 9706f17eab848b9b449df359a952e358d1cf0539..f1b8e06e22432c63c872c97a3991493671a6a3ae 100644 --- a/clang-tools-extra/pseudo/lib/grammar/GrammarBNF.cpp +++ b/clang-tools-extra/pseudo/lib/grammar/GrammarBNF.cpp @@ -33,11 +33,11 @@ public: assert(llvm::all_of(Specs, [](const RuleSpec &R) { - if (R.Target.endswith(OptSuffix)) + if (R.Target.ends_with(OptSuffix)) return false; return llvm::all_of( R.Sequence, [](const RuleSpec::Element &E) { - return !E.Symbol.endswith(OptSuffix); + return !E.Symbol.ends_with(OptSuffix); }); }) && "Optional symbols should be eliminated!"); @@ -225,7 +225,7 @@ private: Chunk = Chunk.trim(); if (Chunk.empty()) continue; // skip empty - if (Chunk.startswith("[") && Chunk.endswith("]")) { + if (Chunk.starts_with("[") && Chunk.ends_with("]")) { if (Out.Sequence.empty()) continue; @@ -241,7 +241,7 @@ private: bool parseAttributes( llvm::StringRef Content, std::vector> &Out) { - assert(Content.startswith("[") && Content.endswith("]")); + assert(Content.starts_with("[") && Content.ends_with("]")); auto KV = Content.drop_front().drop_back().split('='); Out.push_back({KV.first, KV.second.trim()}); @@ -299,7 +299,7 @@ private: if (Elements.empty()) return CB(); auto Front = Elements.front(); - if (!Front.Symbol.endswith(OptSuffix)) { + if (!Front.Symbol.ends_with(OptSuffix)) { Result.push_back(std::move(Front)); eliminateOptionalTail(Elements.drop_front(1), Result, CB); Result.pop_back(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19f2344de4a650692456723648faaf36bfcf7230 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp @@ -0,0 +1,118 @@ +// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-unused-local-non-trivial-variable %t -- \ +// RUN: -config="{CheckOptions: {bugprone-unused-local-non-trivial-variable.IncludeTypes: '::async::Future;::async::Foo.*', bugprone-unused-local-non-trivial-variable.ExcludeTypes: '::async::FooBar'}}" \ +// RUN: -- -fexceptions + +namespace async { +template +class Ptr { + public: + explicit Ptr(T Arg) : Underlying(new T(Arg)) {} + T& operator->() { + return Underlying; + } + ~Ptr() { + delete Underlying; + } + private: + T* Underlying; +}; + +template +class Future { +public: + T get() { + return Pending; + } + ~Future(); +private: + T Pending; +}; + +class FooBar { + public: + ~FooBar(); + private: + Future Fut; +}; + +class FooQux { + public: + ~FooQux(); + private: + Future Fut; +}; + +class FizzFoo { + public: + ~FizzFoo(); + private: + Future Fut; +}; + +} // namespace async + +// Warning is still emitted if there are type aliases. +namespace a { +template +using Future = async::Future; +} // namespace a + +void releaseUnits(); +struct Units { + ~Units() { + releaseUnits(); + } +}; +a::Future acquireUnits(); + +template +T qux(T Generic) { + async::Future PendingA = acquireUnits(); + auto PendingB = acquireUnits(); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future' (aka 'Future') [bugprone-unused-local-non-trivial-variable] + async::Future MustBeUsed; + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unused local variable 'MustBeUsed' of type 'async::Future' [bugprone-unused-local-non-trivial-variable] + PendingA.get(); + async::Future TemplateType; + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'TemplateType' of type 'async::Future' [bugprone-unused-local-non-trivial-variable] + a::Future AliasTemplateType; + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future' (aka 'Future') [bugprone-unused-local-non-trivial-variable] + return Generic; +} + +async::Future Global; + +int bar(int Num) { + a::Future PendingA = acquireUnits(); + a::Future PendingB = acquireUnits(); // not used at all, unused variable not fired because of destructor side effect + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'PendingB' of type 'a::Future' (aka 'Future') [bugprone-unused-local-non-trivial-variable] + auto Num2 = PendingA.get(); + auto Num3 = qux(Num); + async::Ptr> Shared = async::Ptr>(acquireUnits()); + static auto UnusedStatic = async::Future(); + thread_local async::Future UnusedThreadLocal; + auto Captured = acquireUnits(); + Num3 += [Captured]() { + return 1; + }(); + a::Future Referenced = acquireUnits(); + a::Future* Pointer = &Referenced; + a::Future& Reference = Referenced; + const a::Future& ConstReference = Referenced; + try { + } catch (a::Future Fut) { + } + struct Holder { + a::Future Fut; + }; + Holder H; + auto [fut] = H; + return Num * Num3; +} + +void exclusion() { + async::FizzFoo A; + async::FooBar B; + async::FooQux C; + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unused local variable 'C' of type 'async::FooQux' [bugprone-unused-local-non-trivial-variable] +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-ignore-extern-c.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-ignore-extern-c.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a845a0bcc3509c885d0119f0d7b32b7a0ff37e8 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using-ignore-extern-c.cpp @@ -0,0 +1,14 @@ +// RUN: %check_clang_tidy %s modernize-use-using %t -- -config="{CheckOptions: {modernize-use-using.IgnoreExternC: true}}" -- -I %S/Input/use-using/ + +// Some Header +extern "C" { + +typedef int NewInt; +} + +extern "C++" { + +typedef int InExternCPP; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using] +// CHECK-FIXES: using InExternCPP = int; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp index 422abee11a71962cf2229aa51ea6e86fac0f1b45..462bc984fd3ad5609fabde7a313d9c03e4de8abd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp @@ -325,3 +325,20 @@ typedef bool (*ISSUE_65055_2)(int); typedef class ISSUE_67529_1 *ISSUE_67529; // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' // CHECK-FIXES: using ISSUE_67529 = class ISSUE_67529_1 *; + +// Some Header +extern "C" { + +typedef int InExternC; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using] +// CHECK-FIXES: using InExternC = int; + +} + +extern "C++" { + +typedef int InExternCPP; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using] +// CHECK-FIXES: using InExternCPP = int; + +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-anon-record-fields.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-anon-record-fields.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b4d4e924a72171e3db1b64553f78f8a5bcfa35d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-anon-record-fields.cpp @@ -0,0 +1,185 @@ +// RUN: %check_clang_tidy -std=c++20 %s readability-identifier-naming %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-identifier-naming.CheckAnonFieldInParent: true, \ +// RUN: readability-identifier-naming.ClassConstantCase: CamelCase, \ +// RUN: readability-identifier-naming.ClassConstantPrefix: 'k', \ +// RUN: readability-identifier-naming.ClassMemberCase: CamelCase, \ +// RUN: readability-identifier-naming.ConstantCase: UPPER_CASE, \ +// RUN: readability-identifier-naming.ConstantSuffix: '_CST', \ +// RUN: readability-identifier-naming.ConstexprVariableCase: lower_case, \ +// RUN: readability-identifier-naming.GlobalConstantCase: UPPER_CASE, \ +// RUN: readability-identifier-naming.GlobalVariableCase: lower_case, \ +// RUN: readability-identifier-naming.GlobalVariablePrefix: 'g_', \ +// RUN: readability-identifier-naming.LocalConstantCase: CamelCase, \ +// RUN: readability-identifier-naming.LocalConstantPrefix: 'k', \ +// RUN: readability-identifier-naming.LocalVariableCase: lower_case, \ +// RUN: readability-identifier-naming.MemberCase: CamelCase, \ +// RUN: readability-identifier-naming.MemberPrefix: 'm_', \ +// RUN: readability-identifier-naming.ConstantMemberCase: lower_case, \ +// RUN: readability-identifier-naming.PrivateMemberPrefix: '__', \ +// RUN: readability-identifier-naming.ProtectedMemberPrefix: '_', \ +// RUN: readability-identifier-naming.PublicMemberCase: lower_case, \ +// RUN: readability-identifier-naming.StaticConstantCase: UPPER_CASE, \ +// RUN: readability-identifier-naming.StaticVariableCase: camelBack, \ +// RUN: readability-identifier-naming.StaticVariablePrefix: 's_', \ +// RUN: readability-identifier-naming.VariableCase: lower_case, \ +// RUN: readability-identifier-naming.GlobalPointerCase: CamelCase, \ +// RUN: readability-identifier-naming.GlobalPointerSuffix: '_Ptr', \ +// RUN: readability-identifier-naming.GlobalConstantPointerCase: UPPER_CASE, \ +// RUN: readability-identifier-naming.GlobalConstantPointerSuffix: '_Ptr', \ +// RUN: readability-identifier-naming.LocalPointerCase: CamelCase, \ +// RUN: readability-identifier-naming.LocalPointerPrefix: 'l_', \ +// RUN: readability-identifier-naming.LocalConstantPointerCase: CamelCase, \ +// RUN: readability-identifier-naming.LocalConstantPointerPrefix: 'lc_', \ +// RUN: }}' + +static union { + int global; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for global variable 'global' +// CHECK-FIXES: {{^}} int g_global;{{$}} + + const int global_const; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for global constant 'global_const' +// CHECK-FIXES: {{^}} const int GLOBAL_CONST;{{$}} + + int *global_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for global pointer 'global_ptr' +// CHECK-FIXES: {{^}} int *GlobalPtr_Ptr;{{$}} + + int *const global_const_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: invalid case style for global constant pointer 'global_const_ptr' +// CHECK-FIXES: {{^}} int *const GLOBAL_CONST_PTR_Ptr;{{$}} +}; + +namespace ns { + +static union { + int ns_global; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for global variable 'ns_global' +// CHECK-FIXES: {{^}} int g_ns_global;{{$}} + + const int ns_global_const; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for global constant 'ns_global_const' +// CHECK-FIXES: {{^}} const int NS_GLOBAL_CONST;{{$}} + + int *ns_global_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for global pointer 'ns_global_ptr' +// CHECK-FIXES: {{^}} int *NsGlobalPtr_Ptr;{{$}} + + int *const ns_global_const_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: invalid case style for global constant pointer 'ns_global_const_ptr' +// CHECK-FIXES: {{^}} int *const NS_GLOBAL_CONST_PTR_Ptr;{{$}} +}; + +namespace { + +union { + int anon_ns_global; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for global variable 'anon_ns_global' +// CHECK-FIXES: {{^}} int g_anon_ns_global;{{$}} + + const int anon_ns_global_const; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for global constant 'anon_ns_global_const' +// CHECK-FIXES: {{^}} const int ANON_NS_GLOBAL_CONST;{{$}} + + int *anon_ns_global_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for global pointer 'anon_ns_global_ptr' +// CHECK-FIXES: {{^}} int *AnonNsGlobalPtr_Ptr;{{$}} + + int *const anon_ns_global_const_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: invalid case style for global constant pointer 'anon_ns_global_const_ptr' +// CHECK-FIXES: {{^}} int *const ANON_NS_GLOBAL_CONST_PTR_Ptr;{{$}} +}; + +} + +} + + +class Foo { +public: + union { + int PubMember; +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for public member 'PubMember' +// CHECK-FIXES: {{^}} int pub_member;{{$}} + + const int PubConstMember; +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for constant member 'PubConstMember' +// CHECK-FIXES: {{^}} const int pub_const_member;{{$}} + + int *PubPtrMember; +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for public member 'PubPtrMember' +// CHECK-FIXES: {{^}} int *pub_ptr_member;{{$}} + + int *const PubConstPtrMember; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for constant member 'PubConstPtrMember' +// CHECK-FIXES: {{^}} int *const pub_const_ptr_member;{{$}} + }; + +protected: + union { + int prot_member; +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for protected member 'prot_member' +// CHECK-FIXES: {{^}} int _prot_member;{{$}} + + const int prot_const_member; + + int *prot_ptr_member; +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for protected member 'prot_ptr_member' +// CHECK-FIXES: {{^}} int *_prot_ptr_member;{{$}} + + int *const prot_const_ptr_member; + }; + + +private: + union { + int pri_member; +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for private member 'pri_member' +// CHECK-FIXES: {{^}} int __pri_member;{{$}} + + const int pri_const_member; + + int *pri_ptr_member; +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for private member 'pri_ptr_member' +// CHECK-FIXES: {{^}} int *__pri_ptr_member;{{$}} + + int *const pri_const_ptr_member; + }; +}; + +void test() { + union { + int local; + + const int local_const; +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for local constant 'local_const' +// CHECK-FIXES: {{^}} const int kLocalConst;{{$}} + + int *local_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for local pointer 'local_ptr' +// CHECK-FIXES: {{^}} int *l_LocalPtr;{{$}} + + int *const local_const_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for local constant pointer 'local_const_ptr' +// CHECK-FIXES: {{^}} int *const lc_LocalConstPtr;{{$}} + }; + + static union { + int local_static; +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for static variable 'local_static' +// CHECK-FIXES: {{^}} int s_localStatic;{{$}} + + const int local_static_const; +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for static constant 'local_static_const' +// CHECK-FIXES: {{^}} const int LOCAL_STATIC_CONST;{{$}} + + int *local_static_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for static variable 'local_static_ptr' +// CHECK-FIXES: {{^}} int *s_localStaticPtr;{{$}} + + int *const local_static_const_ptr; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for static constant 'local_static_const_ptr' +// CHECK-FIXES: {{^}} int *const LOCAL_STATIC_CONST_PTR;{{$}} + }; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/misleading-indentation.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/misleading-indentation.cpp index aea0618d120db64c7b65eaad3d63e36f175a5511..5d4d60f5f1a3518e3a21a0e397e5857eb38bb8db 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/misleading-indentation.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/misleading-indentation.cpp @@ -4,6 +4,8 @@ void foo1(); void foo2(); void foo3(); +#define E + #define BLOCK \ if (cond1) \ foo1(); \ @@ -109,6 +111,13 @@ void f() } BLOCK + + if (cond1) + foo1(); + else + foo2(); + E foo3(); + // CHECK-MESSAGES-NOT: :[[@LINE-1]]readability-misleading-indentation } void g(bool x) { diff --git a/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap b/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap index fbb8e7db4d10c280bc49180cc4d91c92b348fc09..64180adf5beb358bc34636b89a7ee8f71d34b8b1 100644 --- a/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap +++ b/clang-tools-extra/test/modularize/Inputs/CompileError/module.modulemap @@ -1,4 +1,4 @@ -// module.map +// module.modulemap module Level1A { header "Level1A.h" diff --git a/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap b/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap index d2b0957b76e1cae81541a3777e7928901091c676..39af7d5dcf366e83ac9ea19f613283d408f995de 100644 --- a/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap +++ b/clang-tools-extra/test/modularize/Inputs/CoverageNoProblems/module.modulemap @@ -1,4 +1,4 @@ -// module.map +// module.modulemap module Level1A { header "Includes1/Level1A.h" diff --git a/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap b/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap index dbe0bb8507cf0beb0e984ff761b127cca402825c..2b8b23054a01957c73bdc12bb2a201b2838be733 100644 --- a/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap +++ b/clang-tools-extra/test/modularize/Inputs/CoverageProblems/module.modulemap @@ -1,4 +1,4 @@ -// module.map +// module.modulemap module Level1A { header "Level1A.h" diff --git a/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap b/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap index daa06fca78d26b90a6e0c029812a4c59d4606298..9acb4923f9ac3747548fc900c2c01ab138a08b23 100644 --- a/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap +++ b/clang-tools-extra/test/modularize/Inputs/MissingHeader/module.modulemap @@ -1,4 +1,4 @@ -// module.map +// module.modulemap module Level1A { header "Level1A.h" diff --git a/clang-tools-extra/test/pp-trace/Inputs/module.map b/clang-tools-extra/test/pp-trace/Inputs/module.modulemap similarity index 84% rename from clang-tools-extra/test/pp-trace/Inputs/module.map rename to clang-tools-extra/test/pp-trace/Inputs/module.modulemap index 31f33c5bb149025efd159c77b9fb3686e29f5c1f..f16bbc6e2e05b4d50ab56ce84b9efa1b5cffad06 100644 --- a/clang-tools-extra/test/pp-trace/Inputs/module.map +++ b/clang-tools-extra/test/pp-trace/Inputs/module.modulemap @@ -1,4 +1,4 @@ -// module.map +// module.modulemap module Level1A { header "Level1A.h" diff --git a/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp b/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp index feb7ae913f9968487ebfbe82d3e12d44132e6cb1..e9ab987e493c41a2fcb701a1195ab0ae0f7560e6 100644 --- a/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp +++ b/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp @@ -66,7 +66,7 @@ protected: "#define SOME_MACRO(x) using x\n"; std::vector Errors; std::vector Args; - if (!StringRef(Filename).endswith(".cpp")) { + if (!StringRef(Filename).ends_with(".cpp")) { Args.emplace_back("-xc++-header"); } test::runCheckOnCode( diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 2ca6db02e58791d5f4ea9f6b8e57dccbb425da89..9f814478c4550398b61a4040ce52245455807327 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -167,6 +167,23 @@ endif() include(CheckIncludeFile) check_include_file(sys/resource.h CLANG_HAVE_RLIMITS) +# This check requires _GNU_SOURCE on linux +check_include_file(dlfcn.h CLANG_HAVE_DLFCN_H) +if( CLANG_HAVE_DLFCN_H ) + include(CheckLibraryExists) + include(CheckSymbolExists) + check_library_exists(dl dlopen "" HAVE_LIBDL) + if( HAVE_LIBDL ) + list(APPEND CMAKE_REQUIRED_LIBRARIES dl) + endif() + list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) + check_symbol_exists(dladdr dlfcn.h CLANG_HAVE_DLADDR) + list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) + if( HAVE_LIBDL ) + list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES dl) + endif() +endif() + set(CLANG_RESOURCE_DIR "" CACHE STRING "Relative directory from the Clang binary to its resource files.") diff --git a/clang/bindings/python/README.txt b/clang/bindings/python/README.txt index b0f0142a56f11603e30ee9bbcc38ad6e3bbb3be8..44c715e5de56f763252124e7c84ecd045dc646e3 100644 --- a/clang/bindings/python/README.txt +++ b/clang/bindings/python/README.txt @@ -8,7 +8,7 @@ You may need to set CLANG_LIBRARY_PATH so that the Clang library can be found. The unit tests are designed to be run with any standard test runner. For example: -- -$ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \ +$ env PYTHONPATH=$(echo ~/llvm/clang/bindings/python/) \ CLANG_LIBRARY_PATH=$(llvm-config --libdir) \ python -m unittest discover -v tests.cindex.test_index.test_create ... ok diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 6a16f3a9ef6e9570d5427cc40f34c835e72af343..d780ee353a133cb5a42e4c1e55a05174f720adc7 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -535,7 +535,7 @@ class Diagnostic(object): class FixIt(object): """ A FixIt represents a transformation to be applied to the source to - "fix-it". The fix-it shouldbe applied by replacing the given source range + "fix-it". The fix-it should be applied by replacing the given source range with the given value. """ diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 4b9085d99378c6fb28fb11d509bcf4df4b777d5b..c4673c8a54c5ef531f2e77502d4338ce29c7a52d 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -336,6 +336,7 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-symbolizer llvm-undname llvm-xray + opt-viewer sancov scan-build-py CACHE STRING "") diff --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst index f52f35550d03eb6d980a4ff25781ad371883f2cc..8d4017b29fb8eeb5d76149e7241f31cdad7ed1e1 100644 --- a/clang/docs/ClangFormat.rst +++ b/clang/docs/ClangFormat.rst @@ -131,6 +131,27 @@ An easy way to create the ``.clang-format`` file is: Available style options are described in :doc:`ClangFormatStyleOptions`. +You can create ``.clang-format-ignore`` files to make ``clang-format`` ignore +certain files. A ``.clang-format-ignore`` file consists of patterns of file path +names. It has the following format: + +* A blank line is skipped. +* Leading and trailing spaces of a line are trimmed. +* A line starting with a hash (``#``) is a comment. +* A non-comment line is a single pattern. +* The slash (``/``) is used as the directory separator. +* A pattern is relative to the directory of the ``.clang-format-ignore`` file + (or the root directory if the pattern starts with a slash). +* Patterns follow the rules specified in `POSIX 2.13.1, 2.13.2, and Rule 1 of + 2.13.3 `_. +* A pattern is negated if it starts with a bang (``!``). + +To match all files in a directory, use e.g. ``foo/bar/*``. To match all files in +the directory of the ``.clang-format-ignore`` file, use ``*``. +Multiple ``.clang-format-ignore`` files are supported similar to the +``.clang-format`` files, with a lower directory level file voiding the higher +level ones. Vim Integration =============== diff --git a/clang/docs/ControlFlowIntegrityDesign.rst b/clang/docs/ControlFlowIntegrityDesign.rst index f3a3c8294f7c70da0f27f6a8d0502c3313ece0fa..d66bd16155a9f1346360c20a3a7b4e7c7ea635bd 100644 --- a/clang/docs/ControlFlowIntegrityDesign.rst +++ b/clang/docs/ControlFlowIntegrityDesign.rst @@ -349,7 +349,7 @@ address point. Note that libraries like libcxxabi do assume this property. (2) virtual function entry layout property -For each virtual function the distance between an virtual table entry for this function and the corresponding +For each virtual function the distance between a virtual table entry for this function and the corresponding address point is always the same. This property ensures that dynamic dispatch still works with the interleaving layout. Note that the interleaving scheme in the CFI implementation guarantees both properties above whereas the original scheme proposed diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 13fb7c345aa4ebf3bd9be20ed2284bf40f9a02b6..23a7f4f5d5b926aadd2752d4c808ec59b5fbf401 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -2019,7 +2019,7 @@ would be +1. ``ns_returns_autoreleased`` specifies that the returned object is autorelease pool. **Usage**: The ``ns_consumed`` and ``cf_consumed`` attributes can be placed on -an parameter declaration; they specify that the argument is expected to have a +a parameter declaration; they specify that the argument is expected to have a +1 retain count, which will be balanced in some way by the function or method. The ``ns_consumes_self`` attribute can only be placed on an Objective-C method; it specifies that the method expects its ``self`` parameter to have a @@ -3601,7 +3601,7 @@ scalar calls of ``__builtin_isfpclass`` applied to the input elementwise. The result of ``__builtin_isfpclass`` is a boolean value, if the first argument is a scalar, or an integer vector with the same element count as the first argument. The element type in this vector has the same bit length as the -element of the the first argument type. +element of the first argument type. This function never raises floating-point exceptions and does not canonicalize its input. The floating-point argument is not promoted, its data class is @@ -4959,7 +4959,7 @@ Clang supports the following match rules: - ``record(unless(is_union))``: Can be used to apply attributes only to ``struct`` and ``class`` declarations. -- ``enum``: Can be be used to apply attributes to enumeration declarations. +- ``enum``: Can be used to apply attributes to enumeration declarations. - ``enum_constant``: Can be used to apply attributes to enumerators. diff --git a/clang/docs/LibASTMatchersTutorial.rst b/clang/docs/LibASTMatchersTutorial.rst index 37c9f178fa8df31e47c89cf8e0a61d6c7d163fde..2a58502a8de4e75bb2408421c710cb6a8ccfaccc 100644 --- a/clang/docs/LibASTMatchersTutorial.rst +++ b/clang/docs/LibASTMatchersTutorial.rst @@ -50,7 +50,7 @@ Okay. Now we'll build Clang! cd ~/clang-llvm mkdir build && cd build - cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_BUILD_TESTS=ON # Enable tests; default is off. + cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TESTS=ON ninja ninja check # Test LLVM only. ninja clang-test # Test Clang only. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 066e4ac5b9e54b83965d0cbc64740f12a06aaa0f..0c8fec691bf3c90c33702bb93630d0ef7d40cec3 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -199,11 +199,6 @@ C Language Changes - ``structs``, ``unions``, and ``arrays`` that are const may now be used as constant expressions. This change is more consistent with the behavior of GCC. -- Clang now supports the C-only attribute ``counted_by``. When applied to a - struct's flexible array member, it points to the struct field that holds the - number of elements in the flexible array member. This information can improve - the results of the array bound sanitizer and the - ``__builtin_dynamic_object_size`` builtin. - Enums will now be represented in TBAA metadata using their actual underlying integer type. Previously they were treated as chars, which meant they could alias with all other types. @@ -258,7 +253,7 @@ New Compiler Flags the preprocessed text to the output. This can greatly reduce the size of the preprocessed output, which can be helpful when trying to reduce a test case. * ``-fassume-nothrow-exception-dtor`` is added to assume that the destructor of - an thrown exception object will not throw. The generated code for catch + a thrown exception object will not throw. The generated code for catch handlers will be smaller. A throw expression of a type with a potentially-throwing destructor will lead to an error. @@ -521,6 +516,9 @@ Improvements to Clang's diagnostics | ~~~~~~~^~~~~ - Clang now diagnoses definitions of friend function specializations, e.g. ``friend void f<>(int) {}``. +- Clang now diagnoses narrowing conversions involving const references. + (`#63151: `_). + Improvements to Clang's time-trace ---------------------------------- @@ -685,6 +683,12 @@ Bug Fixes in This Version (`#62157 `_) and (`#64885 `_) and (`#65568 `_) +- Fix an issue where clang doesn't respect detault template arguments that + are added in a later redeclaration for CTAD. + Fixes (#69987 `_) +- Fix an issue where CTAD fails for explicit type conversion. + Fixes (#64347 `_) + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -968,6 +972,9 @@ RISC-V Support - Unaligned memory accesses can be toggled by ``-m[no-]unaligned-access`` or the aliases ``-m[no-]strict-align``. +- Default ABI with F but without D was changed to ilp32f for RV32 and to lp64f + for RV64. + CUDA/HIP Language Changes ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1034,6 +1041,7 @@ clang-format - Add ``BreakAdjacentStringLiterals`` option. - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property attributes (like ``nonatomic, strong, nullable``). +- Add ``.clang-format-ignore`` files. libclang -------- @@ -1045,18 +1053,119 @@ libclang Static Analyzer --------------- +New features +^^^^^^^^^^^^ + +- Implemented the ``[[clang::suppress]]`` attribute for suppressing diagnostics + of static analysis tools, such as the Clang Static Analyzer. + `Documentation `__. + +- Added support for the ``cleanup`` attribute. + `Documentation `__. + +- Support "Deducing this" (P0847R7). (Worked out of the box) + (`af4751738db8 `__) + - Added a new checker ``core.BitwiseShift`` which reports situations where bitwise shift operators produce undefined behavior (because some operand is negative or too large). + `Documentation `__. + +- Added a new experimental checker ``alpha.core.StdVariant`` to detect variant + accesses via wrong alternatives. + `Documentation `__. + (`#66481 `_) + +- Added a new experimental checker ``alpha.cplusplus.ArrayDelete`` to detect + destructions of arrays of polymorphic objects that are destructed as their + base class (`CERT EXP51-CPP `_). + `Documentation `__. + (`0e246bb67573 `_) + +- Added a new checker configuration option ``InvalidatingGetEnv=[true,false]`` to + ``security.cert.env.InvalidPtr``. It's not set by default. + If set, ``getenv`` calls won't invalidate previously returned pointers. + `Documentation `__. + (`#67663 `_) + +Crash and bug fixes +^^^^^^^^^^^^^^^^^^^ -- Move checker ``alpha.unix.Errno`` out of the ``alpha`` package - to ``unix.Errno``. +- Fixed a crash caused by ``builtin_bit_cast``. + (`#69922 `_) -- Move checker ``alpha.unix.StdCLibraryFunctions`` out of the ``alpha`` package - to ``unix.StdCLibraryFunctions``. +- Fixed a ``core.StackAddressEscape`` crash on temporary object fields. + (`#66221 `_) + +- A few crashes have been found and fixed using randomized testing related + to the use of ``_BitInt()`` in tidy checks and in clang analysis. + (`#67212 `_, + `#66782 `_, + `#65889 `_, + `#65888 `_, + `#65887 `_) + +- Fixed note links of the HTML output. + (`#64054 `_) + +- Allow widening rage-based for loops. + (`#70190 `_) + +- Fixed uninitialized base class with initializer list when ctor is not + declared in the base class. + (`#70464 `_, + `#59493 `_, + `#54533 `_) + +- Fixed an ``alpha.unix.cstring`` crash on variadic functions. + (`#74269 `_) - Fix false positive in mutation check when using pointer to member function. - (`#66204: `_). + (`#66204 `_) + +Improvements +^^^^^^^^^^^^ + +- Improved the ``unix.StdCLibraryFunctions`` checker by modeling more + functions like ``send``, ``recv``, ``readlink``, ``fflush`` and + ``errno`` behavior. + (`52ac71f92d38 `_, + `#71373 `_, + `#76557 `_, + `#71392 `_) + +- Fixed a false negative for when accessing a nonnull property (ObjC). + (`1dceba3a3684 `_) + +- ``security.insecureAPI.DeprecatedOrUnsafeBufferHandling`` now considers + ``fprintf`` calls unsafe. + `Documentation `__. + +- Improved the diagnostics of the ``optin.core.EnumCastOutOfRange`` checker. + It will display the name and the declaration of the enumeration along with + the concrete value being cast to the enum. + (`#74503 `_) + +- Improved the ``alpha.security.ArrayBoundV2`` checker for detecting buffer + accesses prior the buffer; and also reworked the diagnostic messages. + (`3e014038b373 `_, + `#70056 `_, + `#72107 `_) + +- Improved the ``alpha.unix.cstring.OutOfBounds`` checking both ends of the + buffers in more cases. + (`c3a87ddad62a `_, + `0954dc3fb921 `_) + +- Improved the ``alpha.unix.Stream`` checker by modeling more functions like, + ``fflush``, ``fputs``, ``fgetc``, ``fputc``, ``fopen``, ``fopen``, ``fgets``. + (`#74296 `_, + `#73335 `_, + `#72627 `_, + `#71518 `_, + `#72016 `_, + `#70540 `_, + `#73638 `_) - The ``alpha.security.taint.TaintPropagation`` checker no longer propagates taint on ``strlen`` and ``strnlen`` calls, unless these are marked @@ -1065,16 +1174,32 @@ Static Analyzer Read the PR for the details. (`#66086 `_) -- A few crashes have been found and fixed using randomized testing related - to the use of ``_BitInt()`` in tidy checks and in clang analysis. See - `#67212 `_, - `#66782 `_, - `#65889 `_, - `#65888 `_, and - `#65887 `_ +- Other taint-related improvements. + (`#66358 `_, + `#66074 `_, + `#66358 `_) + +- Checkers can query constraint bounds to improve diagnostic messages. + (`#74141 `_) + +Moved checkers +^^^^^^^^^^^^^^ + +- Move checker ``alpha.unix.Errno`` out of the ``alpha`` package + to ``unix.Errno``. + `Documentation `__. + +- Move checker ``alpha.unix.StdCLibraryFunctions`` out of the ``alpha`` package + to ``unix.StdCLibraryFunctions``. + `Documentation `__. + +- Move checker ``alpha.security.cert.env.InvalidPtr`` out of the ``alpha`` + package to ``security.cert.env.InvalidPtr``. + `Documentation `__. - Move checker ``alpha.cplusplus.EnumCastOutOfRange`` out of the ``alpha`` package to ``optin.core.EnumCastOutOfRange``. + `Documentation `__. .. _release-notes-sanitizers: diff --git a/clang/docs/SanitizerCoverage.rst b/clang/docs/SanitizerCoverage.rst index c7ced397c72239e46c49138c0df305a290d2b048..45ad03cb43774c6b8448659b464624e8cfd99f93 100644 --- a/clang/docs/SanitizerCoverage.rst +++ b/clang/docs/SanitizerCoverage.rst @@ -496,7 +496,7 @@ offsets in the corresponding binary/DSO that were executed during the run. Sancov Tool ----------- -An simple ``sancov`` tool is provided to process coverage files. +A simple ``sancov`` tool is provided to process coverage files. The tool is part of LLVM project and is currently supported only on Linux. It can handle symbolization tasks autonomously without any extra support from the environment. You need to pass .sancov files (named diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 81d40395067c9aeeac28b382b79042820aaa9a0b..bb637cf1b8007bb2ac18d0ce2ab450fee78a997a 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1025,7 +1025,7 @@ security.insecureAPI.vfork (C) security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C) """"""""""""""""""""""""""""""""""""""""""""""""""""""""" - Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: ``sprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset`` + Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: ``sprintf, fprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset`` .. code-block:: c @@ -2095,6 +2095,21 @@ This checker is a part of ``core.StackAddressEscape``, but is temporarily disabl // returned block } +.. _alpha-core-StdVariant: + +alpha.core.StdVariant (C++) +""""""""""""""""""""""""""" +Check if a value of active type is retrieved from an ``std::variant`` instance with ``std::get``. +In case of bad variant type access (the accessed type differs from the active type) +a warning is emitted. Currently, this checker does not take exception handling into account. + +.. code-block:: cpp + + void test() { + std::variant v = 25; + char c = stg::get(v); // warn: "int" is the active alternative + } + .. _alpha-core-TestAfterDivZero: alpha.core.TestAfterDivZero (C) diff --git a/clang/include/clang-c/BuildSystem.h b/clang/include/clang-c/BuildSystem.h index 296e61247cef572973533f267ac973dde62cc359..57e16af20a70065013b2f29bca7aaa21ed585a57 100644 --- a/clang/include/clang-c/BuildSystem.h +++ b/clang/include/clang-c/BuildSystem.h @@ -95,7 +95,7 @@ CINDEX_LINKAGE void clang_free(void *buffer); CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay); /** - * Object encapsulating information about a module.map file. + * Object encapsulating information about a module.modulemap file. */ typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor; @@ -109,7 +109,7 @@ CINDEX_LINKAGE CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned options); /** - * Sets the framework module name that the module.map describes. + * Sets the framework module name that the module.modulemap describes. * \returns 0 for success, non-zero to indicate an error. */ CINDEX_LINKAGE enum CXErrorCode @@ -117,7 +117,7 @@ clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor, const char *name); /** - * Sets the umbrella header name that the module.map describes. + * Sets the umbrella header name that the module.modulemap describes. * \returns 0 for success, non-zero to indicate an error. */ CINDEX_LINKAGE enum CXErrorCode diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index cd0878d7082514c600bcb8bf547d91f1d96093db..a807bcdd76b30d8f7bf91e30391fb97d19419b51 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -358,7 +358,8 @@ public: /// /// \param IsKnownNewer \c true if this declaration is known to be newer /// than \p OldD (for instance, if this declaration is newly-created). - bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const; + bool declarationReplaces(const NamedDecl *OldD, + bool IsKnownNewer = true) const; /// Determine whether this declaration has linkage. bool hasLinkage() const; @@ -4332,30 +4333,6 @@ public: return field_begin() == field_end(); } - FieldDecl *getLastField() { - FieldDecl *FD = nullptr; - for (FieldDecl *Field : fields()) - FD = Field; - return FD; - } - const FieldDecl *getLastField() const { - return const_cast(this)->getLastField(); - } - - template - const FieldDecl *findFieldIf(Functor &Pred) const { - for (const Decl *D : decls()) { - if (const auto *FD = dyn_cast(D); FD && Pred(FD)) - return FD; - - if (const auto *RD = dyn_cast(D)) - if (const FieldDecl *FD = RD->findFieldIf(Pred)) - return FD; - } - - return nullptr; - } - /// Note that the definition of this type is now complete. virtual void completeDefinition(); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 5b1038582bc674700132386ff9687ef30ad86592..10dcbdb262d84e40c58b72a25a33e2ef5cf1ab0b 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -19,7 +19,6 @@ #include "clang/AST/SelectorLocationsKind.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/ArrayRef.h" @@ -489,15 +488,6 @@ public: // Return true if this is a FileContext Decl. bool isFileContextDecl() const; - /// Whether it resembles a flexible array member. This is a static member - /// because we want to be able to call it with a nullptr. That allows us to - /// perform non-Decl specific checks based on the object's type and strict - /// flex array level. - static bool isFlexibleArrayMemberLike( - ASTContext &Context, const Decl *D, QualType Ty, - LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, - bool IgnoreTemplateOrMacroSubstitution); - ASTContext &getASTContext() const LLVM_READONLY; /// Helper to get the language options from the ASTContext. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index c501801b95bd9558b72a01951a175a511d6f8cfe..8f2714e142bbe3ee2898a63e4644c00b514e4f4b 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2036,12 +2036,7 @@ bool RecursiveASTVisitor::TraverseTemplateArgumentLocsHelper( #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ /* The partial specialization. */ \ - if (TemplateParameterList *TPL = D->getTemplateParameters()) { \ - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \ - I != E; ++I) { \ - TRY_TO(TraverseDecl(*I)); \ - } \ - } \ + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ /* The args that remains unspecialized. */ \ TRY_TO(TraverseTemplateArgumentLocsHelper( \ D->getTemplateArgsAsWritten()->getTemplateArgs(), \ diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index b3ae66e6e769d08cad0f7e8ada1384921132b00d..1afa693672860fb2d74db9b2a723fe735f502af8 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2383,10 +2383,6 @@ public: /// Check if the type is the CUDA device builtin texture type. bool isCUDADeviceBuiltinTextureType() const; - bool isRVVType(unsigned ElementCount) const; - - bool isRVVType(unsigned Bitwidth, bool IsFloat, bool IsBFloat = false) const; - /// Return the implicit lifetime for this type, which must not be dependent. Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; @@ -7283,28 +7279,6 @@ inline bool Type::isOpenCLSpecificType() const { isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType(); } -inline bool Type::isRVVType(unsigned ElementCount) const { - bool Ret = false; -#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \ - IsFP, IsBF) \ - if (NumEls == ElementCount) \ - Ret |= isSpecificBuiltinType(BuiltinType::Id); -#include "clang/Basic/RISCVVTypes.def" - return Ret; -} - -inline bool Type::isRVVType(unsigned Bitwidth, bool IsFloat, - bool IsBFloat) const { - bool Ret = false; -#define RVV_TYPE(Name, Id, SingletonId) -#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \ - IsFP, IsBF) \ - if (ElBits == Bitwidth && IsFloat == IsFP && IsBFloat == IsBF) \ - Ret |= isSpecificBuiltinType(BuiltinType::Id); -#include "clang/Basic/RISCVVTypes.def" - return Ret; -} - inline bool Type::isTemplateTypeParmType() const { return isa(CanonicalType); } diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index d7e39ab2616fd90514327ca57ecc0a226cc58590..e8c27d6c12038b280d4132cd5c4ffbe430e4bd3f 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -289,6 +289,22 @@ public: /// `E` must be a glvalue or a `BuiltinType::BuiltinFn` StorageLocation *getStorageLocation(const Expr &E) const; + /// Returns the result of casting `getStorageLocation(...)` to a subclass of + /// `StorageLocation` (using `cast_or_null`). + /// This assert-fails if the result of `getStorageLocation(...)` is not of + /// type `T *`; if the storage location is not guaranteed to have type `T *`, + /// consider using `dyn_cast_or_null(getStorageLocation(...))` instead. + template + std::enable_if_t, T *> + get(const ValueDecl &D) const { + return cast_or_null(getStorageLocation(D)); + } + template + std::enable_if_t, T *> + get(const Expr &E) const { + return cast_or_null(getStorageLocation(E)); + } + /// Returns the storage location assigned to the `this` pointee in the /// environment or null if the `this` pointee has no assigned storage location /// in the environment. @@ -325,7 +341,8 @@ public: /// /// Requirements: /// `E` must be a prvalue of record type. - RecordStorageLocation &getResultObjectLocation(const Expr &RecordPRValue); + RecordStorageLocation & + getResultObjectLocation(const Expr &RecordPRValue) const; /// Returns the return value of the current function. This can be null if: /// - The function has a void return type @@ -434,24 +451,14 @@ public: /// Assigns `Val` as the value of the prvalue `E` in the environment. /// - /// If `E` is not yet associated with a storage location, associates it with - /// a newly created storage location. In any case, associates the storage - /// location of `E` with `Val`. - /// - /// Once the migration to strict handling of value categories is complete - /// (see https://discourse.llvm.org/t/70086), this function will be renamed to - /// `setValue()`. At this point, prvalue expressions will be associated - /// directly with `Value`s, and the legacy behavior of associating prvalue - /// expressions with storage locations (as described above) will be - /// eliminated. - /// /// Requirements: /// - /// `E` must be a prvalue - /// If `Val` is a `RecordValue`, its `RecordStorageLocation` must be the - /// same as that of any `RecordValue` that has already been associated with - /// `E`. This is to guarantee that the result object initialized by a prvalue - /// `RecordValue` has a durable storage location. + /// - `E` must be a prvalue + /// - If `Val` is a `RecordValue`, its `RecordStorageLocation` must be + /// `getResultObjectLocation(E)`. An exception to this is if `E` is an + /// expression that originally creates a `RecordValue` (such as a + /// `CXXConstructExpr` or `CallExpr`), as these establish the location of + /// the result object in the first place. void setValue(const Expr &E, Value &Val); /// Returns the value assigned to `Loc` in the environment or null if `Loc` @@ -466,6 +473,26 @@ public: /// storage location in the environment, otherwise returns null. Value *getValue(const Expr &E) const; + /// Returns the result of casting `getValue(...)` to a subclass of `Value` + /// (using `cast_or_null`). + /// This assert-fails if the result of `getValue(...)` is not of type `T *`; + /// if the value is not guaranteed to have type `T *`, consider using + /// `dyn_cast_or_null(getValue(...))` instead. + template + std::enable_if_t, T *> + get(const StorageLocation &Loc) const { + return cast_or_null(getValue(Loc)); + } + template + std::enable_if_t, T *> + get(const ValueDecl &D) const { + return cast_or_null(getValue(D)); + } + template + std::enable_if_t, T *> get(const Expr &E) const { + return cast_or_null(getValue(E)); + } + // FIXME: should we deprecate the following & call arena().create() directly? /// Creates a `T` (some subclass of `Value`), forwarding `args` to the @@ -608,14 +635,6 @@ private: // The copy-constructor is for use in fork() only. Environment(const Environment &) = default; - /// Internal version of `setStorageLocation()` that doesn't check if the - /// expression is a prvalue. - void setStorageLocationInternal(const Expr &E, StorageLocation &Loc); - - /// Internal version of `getStorageLocation()` that doesn't check if the - /// expression is a prvalue. - StorageLocation *getStorageLocationInternal(const Expr &E) const; - /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise /// return null. /// @@ -708,20 +727,9 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, std::vector getFieldsForInitListExpr(const RecordDecl *RD); /// Associates a new `RecordValue` with `Loc` and returns the new value. -/// It is not defined whether the field values remain the same or not. -/// -/// This function is primarily intended for use by checks that set custom -/// properties on `RecordValue`s to model the state of these values. Such checks -/// should avoid modifying the properties of an existing `RecordValue` because -/// these changes would be visible to other `Environment`s that share the same -/// `RecordValue`. Instead, call `refreshRecordValue()`, then set the properties -/// on the new `RecordValue` that it returns. Typical usage: -/// -/// refreshRecordValue(Loc, Env).setProperty("my_prop", MyPropValue); RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env); /// Associates a new `RecordValue` with `Expr` and returns the new value. -/// See also documentation for the overload above. RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env); } // namespace dataflow diff --git a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h index 7b87840d626b4b608960bfd76edbaf833dff4d6a..783e53e980aa2c7ab42c708786c3e6e45f151bc2 100644 --- a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h @@ -22,19 +22,13 @@ namespace dataflow { /// Copies a record (struct, class, or union) from `Src` to `Dst`. /// /// This performs a deep copy, i.e. it copies every field (including synthetic -/// fields) and recurses on fields of record type. It also copies properties -/// from the `RecordValue` associated with `Src` to the `RecordValue` associated -/// with `Dst` (if these `RecordValue`s exist). +/// fields) and recurses on fields of record type. /// /// If there is a `RecordValue` associated with `Dst` in the environment, this /// function creates a new `RecordValue` and associates it with `Dst`; clients /// need to be aware of this and must not assume that the `RecordValue` /// associated with `Dst` remains the same after the call. /// -/// We create a new `RecordValue` rather than modifying properties on the old -/// `RecordValue` because the old `RecordValue` may be shared with other -/// `Environment`s, and we don't want changes to properties to be visible there. -/// /// Requirements: /// /// `Src` and `Dst` must have the same canonical unqualified type. @@ -49,9 +43,7 @@ void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, /// /// This performs a deep comparison, i.e. it compares every field (including /// synthetic fields) and recurses on fields of record type. Fields of reference -/// type compare equal if they refer to the same storage location. If -/// `RecordValue`s are associated with `Loc1` and Loc2`, it also compares the -/// properties on those `RecordValue`s. +/// type compare equal if they refer to the same storage location. /// /// Note on how to interpret the result: /// - If this returns true, the records are guaranteed to be equal at runtime. diff --git a/clang/include/clang/Analysis/FlowSensitive/Value.h b/clang/include/clang/Analysis/FlowSensitive/Value.h index e6c68e5b4e93e1e8e9071e3c591a393835462988..be1bf9324c87b40583b693ff6044d0f8d2211df6 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Value.h +++ b/clang/include/clang/Analysis/FlowSensitive/Value.h @@ -63,7 +63,11 @@ public: /// Assigns `Val` as the value of the synthetic property with the given /// `Name`. + /// + /// Properties may not be set on `RecordValue`s; use synthetic fields instead + /// (for details, see documentation for `RecordStorageLocation`). void setProperty(llvm::StringRef Name, Value &Val) { + assert(getKind() != Kind::Record); Properties.insert_or_assign(Name, &Val); } @@ -184,33 +188,23 @@ private: /// In C++, prvalues of class type serve only a limited purpose: They can only /// be used to initialize a result object. It is not possible to access member /// variables or call member functions on a prvalue of class type. -/// Correspondingly, `RecordValue` also serves only two limited purposes: -/// - It conveys a prvalue of class type from the place where the object is -/// constructed to the result object that it initializes. +/// Correspondingly, `RecordValue` also serves only a limited purpose: It +/// conveys a prvalue of class type from the place where the object is +/// constructed to the result object that it initializes. /// -/// When creating a prvalue of class type, we already need a storage location -/// for `this`, even though prvalues are otherwise not associated with storage -/// locations. `RecordValue` is therefore essentially a wrapper for a storage -/// location, which is then used to set the storage location for the result -/// object when we process the AST node for that result object. +/// When creating a prvalue of class type, we already need a storage location +/// for `this`, even though prvalues are otherwise not associated with storage +/// locations. `RecordValue` is therefore essentially a wrapper for a storage +/// location, which is then used to set the storage location for the result +/// object when we process the AST node for that result object. /// -/// For example: -/// MyStruct S = MyStruct(3); +/// For example: +/// MyStruct S = MyStruct(3); /// -/// In this example, `MyStruct(3) is a prvalue, which is modeled as a -/// `RecordValue` that wraps a `RecordStorageLocation`. This -// `RecordStorageLocation` is then used as the storage location for `S`. +/// In this example, `MyStruct(3) is a prvalue, which is modeled as a +/// `RecordValue` that wraps a `RecordStorageLocation`. This +/// `RecordStorageLocation` is then used as the storage location for `S`. /// -/// - It allows properties to be associated with an object of class type. -/// Note that when doing so, you should avoid mutating the properties of an -/// existing `RecordValue` in place, as these changes would be visible to -/// other `Environment`s that share the same `RecordValue`. Instead, associate -/// a new `RecordValue` with the `RecordStorageLocation` and set the -/// properties on this new `RecordValue`. (See also `refreshRecordValue()` in -/// DataflowEnvironment.h, which makes this easy.) -/// Note also that this implies that it is common for the same -/// `RecordStorageLocation` to be associated with different `RecordValue`s -/// in different environments. /// Over time, we may eliminate `RecordValue` entirely. See also the discussion /// here: https://reviews.llvm.org/D155204#inline-1503204 class RecordValue final : public Value { diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 0d94ea2851c9ab6bc8e2a8057b517ebc7f9e7af8..db17211747b17d3a48349813a6d4812d74d481f4 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -455,6 +455,9 @@ def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch6 def TargetELF : TargetSpec { let ObjectFormats = ["ELF"]; } +def TargetELFOrMachO : TargetSpec { + let ObjectFormats = ["ELF", "MachO"]; +} def TargetSupportsInitPriority : TargetSpec { let CustomCode = [{ !Target.getTriple().isOSzOS() }]; @@ -1665,7 +1668,7 @@ def IBOutletCollection : InheritableAttr { let Documentation = [Undocumented]; } -def IFunc : Attr, TargetSpecificAttr { +def IFunc : Attr, TargetSpecificAttr { let Spellings = [GCC<"ifunc">]; let Args = [StringArgument<"Resolver">]; let Subjects = SubjectList<[Function]>; @@ -2212,7 +2215,8 @@ def NotTailCalled : InheritableAttr { def : MutualExclusions<[AlwaysInline, NotTailCalled]>; def NoStackProtector : InheritableAttr { - let Spellings = [Clang<"no_stack_protector">, Declspec<"safebuffers">]; + let Spellings = [Clang<"no_stack_protector">, CXX11<"gnu", "no_stack_protector">, + C23<"gnu", "no_stack_protector">, Declspec<"safebuffers">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoStackProtectorDocs]; let SimpleHandler = 1; @@ -2792,9 +2796,10 @@ def SwiftAsyncError : InheritableAttr { let Documentation = [SwiftAsyncErrorDocs]; } -def Suppress : StmtAttr { - let Spellings = [CXX11<"gsl", "suppress">]; +def Suppress : DeclOrStmtAttr { + let Spellings = [CXX11<"gsl", "suppress">, Clang<"suppress">]; let Args = [VariadicStringArgument<"DiagnosticIdentifiers">]; + let Accessors = [Accessor<"isGSL", [CXX11<"gsl", "suppress">]>]; let Documentation = [SuppressDocs]; } @@ -2878,7 +2883,7 @@ def Target : InheritableAttr { for (auto &Feature : AttrFeatures) { Feature = Feature.trim(); - if (Feature.startswith("arch=")) + if (Feature.starts_with("arch=")) return Feature.drop_front(sizeof("arch=") - 1); } return ""; @@ -2896,8 +2901,8 @@ def Target : InheritableAttr { for (auto &Feature : AttrFeatures) { Feature = Feature.trim(); - if (!Feature.startswith("no-") && !Feature.startswith("arch=") && - !Feature.startswith("fpmath=") && !Feature.startswith("tune=")) + if (!Feature.starts_with("no-") && !Feature.starts_with("arch=") && + !Feature.starts_with("fpmath=") && !Feature.starts_with("tune=")) Out.push_back(Feature); } } @@ -4326,24 +4331,6 @@ def AvailableOnlyInDefaultEvalMethod : InheritableAttr { let Documentation = [Undocumented]; } -def CountedBy : InheritableAttr { - let Spellings = [Clang<"counted_by">]; - let Subjects = SubjectList<[Field]>; - let Args = [IdentifierArgument<"CountedByField">]; - let Documentation = [CountedByDocs]; - let LangOpts = [COnly]; - // FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl - // isn't yet available due to the fact that we're still parsing the - // structure. Maybe that code could be changed sometime in the future. - code AdditionalMembers = [{ - private: - SourceRange CountedByFieldLoc; - public: - SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; } - void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; } - }]; -} - def PreferredType: InheritableAttr { let Spellings = [Clang<"preferred_type">]; let Subjects = SubjectList<[BitField], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 1a98196834cefc31a73523b79a82035c408db535..98a7ecc7fd7df3f410a05cc1d67b7c31b5852a21 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5267,7 +5267,74 @@ the ``int`` parameter is the one that represents the error. def SuppressDocs : Documentation { let Category = DocCatStmt; let Content = [{ -The ``[[gsl::suppress]]`` attribute suppresses specific +The ``suppress`` attribute suppresses unwanted warnings coming from static +analysis tools such as the Clang Static Analyzer. The tool will not report +any issues in source code annotated with the attribute. + +The attribute cannot be used to suppress traditional Clang warnings, because +many such warnings are emitted before the attribute is fully parsed. +Consider using ``#pragma clang diagnostic`` to control such diagnostics, +as described in `Controlling Diagnostics via Pragmas +`_. + +The ``suppress`` attribute can be placed on an individual statement in order to +suppress warnings about undesirable behavior occurring at that statement: + +.. code-block:: c++ + + int foo() { + int *x = nullptr; + ... + [[clang::suppress]] + return *x; // null pointer dereference warning suppressed here + } + +Putting the attribute on a compound statement suppresses all warnings in scope: + +.. code-block:: c++ + + int foo() { + [[clang::suppress]] { + int *x = nullptr; + ... + return *x; // warnings suppressed in the entire scope + } + } + +Some static analysis warnings are accompanied by one or more notes, and the +line of code against which the warning is emitted isn't necessarily the best +for suppression purposes. In such cases the tools are allowed to implement +additional ways to suppress specific warnings based on the attribute attached +to a note location. + +For example, the Clang Static Analyzer suppresses memory leak warnings when +the suppression attribute is placed at the allocation site (highlited by +a "note: memory is allocated"), which may be different from the line of code +at which the program "loses track" of the pointer (where the warning +is ultimately emitted): + +.. code-block:: c + + int bar1(bool coin_flip) { + __attribute__((suppress)) + int *result = (int *)malloc(sizeof(int)); + if (coin_flip) + return 1; // warning about this leak path is suppressed + + return *result; // warning about this leak path is also suppressed + } + + int bar2(bool coin_flip) { + int *result = (int *)malloc(sizeof(int)); + if (coin_flip) + return 1; // leak warning on this path NOT suppressed + + __attribute__((suppress)) + return *result; // leak warning is suppressed only on this path + } + + +When written as ``[[gsl::suppress]]``, this attribute suppresses specific clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable way. The attribute can be attached to declarations, statements, and at namespace scope. @@ -5468,7 +5535,9 @@ considered inline. Not all targets support this attribute. ELF target support depends on both the linker and runtime linker, and is available in at least lld 4.0 and later, binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later. -Non-ELF targets currently do not support this attribute. +Mach-O targets support it, but with slightly different semantics: the resolver +is run at first call, instead of at load time by the runtime linker. Targets +other than ELF and Mach-O currently do not support this attribute. }]; } @@ -7431,72 +7500,6 @@ attribute, they default to the value ``65535``. }]; } -def CountedByDocs : Documentation { - let Category = DocCatField; - let Content = [{ -Clang supports the ``counted_by`` attribute on the flexible array member of a -structure in C. The argument for the attribute is the name of a field member in -the same structure holding the count of elements in the flexible array. This -information can be used to improve the results of the array bound sanitizer and -the ``__builtin_dynamic_object_size`` builtin. - -For example, the following code: - -.. code-block:: c - - struct bar; - - struct foo { - size_t count; - char other; - struct bar *array[] __attribute__((counted_by(count))); - }; - -specifies that the flexible array member ``array`` has the number of elements -allocated for it stored in ``count``. This establishes a relationship between -``array`` and ``count``. Specifically, ``p->array`` must have at least -``p->count`` number of elements available. It's the user's responsibility to -ensure that this relationship is maintained through changes to the structure. - -In the following example, the allocated array erroneously has fewer elements -than what's specified by ``p->count``. This would result in an out-of-bounds -access not being detected. - -.. code-block:: c - - #define SIZE_INCR 42 - - struct foo *p; - - void foo_alloc(size_t count) { - p = malloc(MAX(sizeof(struct foo), - offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); - p->count = count + SIZE_INCR; - } - -The next example updates ``p->count``, breaking the relationship requirement -that ``p->array`` must have at least ``p->count`` number of elements available: - -.. code-block:: c - - #define SIZE_INCR 42 - - struct foo *p; - - void foo_alloc(size_t count) { - p = malloc(MAX(sizeof(struct foo), - offsetof(struct foo, array[0]) + count * sizeof(struct bar *))); - p->count = count; - } - - void use_foo(int index) { - p->count += SIZE_INCR + 1; /* 'count' is now larger than the number of elements of 'array'. */ - p->array[index] = 0; /* the sanitizer can't properly check if this is an out-of-bounds access. */ - } - - }]; -} - def CoroOnlyDestroyWhenCompleteDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 82a1ba3c82ad358ef244b2c3649362ef64cf7545..31ec84143f65c1c7d4a0db6d2cffb8f2671e5598 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -68,6 +68,9 @@ TARGET_BUILTIN(__builtin_arm_ldg, "v*v*", "t", "mte") TARGET_BUILTIN(__builtin_arm_stg, "vv*", "t", "mte") TARGET_BUILTIN(__builtin_arm_subp, "Uiv*v*", "t", "mte") +// SME state function +BUILTIN(__builtin_arm_get_sme_state, "vULi*ULi*", "n") + // Memory Operations TARGET_BUILTIN(__builtin_arm_mops_memset_tag, "v*v*iz", "", "mte,mops") diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 8b59b3790d7bc661361cf6f2b8f154877425658a..e562ef04a30194eccf9bcd1c1ab8a490267af29b 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -406,5 +406,23 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", "nc", "fp8-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-insts") +//===----------------------------------------------------------------------===// +// GFX12+ only builtins. +//===----------------------------------------------------------------------===// + +TARGET_BUILTIN(__builtin_amdgcn_permlane16_var, "UiUiUiUiIbIb", "nc", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_permlanex16_var, "UiUiUiUiIbIb", "nc", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal, "vIi", "n", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal_var, "vi", "n", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_barrier_wait, "vIs", "n", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal_isfirst, "bIi", "n", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal_isfirst_var, "bi", "n", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_barrier_init, "vii", "n", "gfx12-insts") +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") + + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsSystemZ.def b/clang/include/clang/Basic/BuiltinsSystemZ.def index 4cfc52ae421686d1750a4143eb674ec4b7fea2d7..f0c0ebfa622a43ef512c977227587b57a01910ce 100644 --- a/clang/include/clang/Basic/BuiltinsSystemZ.def +++ b/clang/include/clang/Basic/BuiltinsSystemZ.def @@ -64,14 +64,14 @@ TARGET_BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc", "vector") // Vector integer instructions (chapter 22 of the PoP) -TARGET_BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vaq, "SLLLiSLLLiSLLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vacq, "ULLLiULLLiULLLiULLLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vaccq, "ULLLiULLLiULLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vacccq, "ULLLiULLLiULLLiULLLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc", "vector") @@ -116,11 +116,11 @@ TARGET_BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmg, "ULLLiV2ULLiV2ULLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmag, "ULLLiV2ULLiV2ULLiULLLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc", "vector") @@ -161,14 +161,14 @@ TARGET_BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsq, "SLLLiSLLLiSLLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsbcbiq, "ULLLiULLLiULLLiULLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsbiq, "ULLLiULLLiULLLiULLLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vscbiq, "ULLLiULLLiULLLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc", "vector") @@ -180,8 +180,8 @@ TARGET_BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc", "vector") -TARGET_BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumqf, "ULLLiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumqg, "ULLLiV2ULLiV2ULLi", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc", "vector") // Vector string instructions (chapter 23 of the PoP) @@ -256,7 +256,7 @@ TARGET_BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc", "vector") TARGET_BUILTIN(__builtin_s390_vlrlr, "V16ScUivC*", "", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vstrlr, "vV16ScUiv*", "", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vbperm, "V2ULLiV16UcV16Uc", "nc", "vector-enhancements-1") -TARGET_BUILTIN(__builtin_s390_vmslg, "V16UcV2ULLiV2ULLiV16UcIi", "nc", "vector-enhancements-1") +TARGET_BUILTIN(__builtin_s390_vmslg, "ULLLiV2ULLiV2ULLiULLLiIi", "nc", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vfmaxdb, "V2dV2dV2dIi", "nc", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vfmindb, "V2dV2dV2dIi", "nc", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vfnmadb, "V2dV2dV2dV2d", "nc", "vector-enhancements-1") diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index e4802f8ab1c15622b278b8eb326955449afc660a..60b752ad48548fc3c0b25aa0a5471b010e061c73 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -979,7 +979,7 @@ TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512p TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_knotdi, "UOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_knotdi, "UOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl") @@ -1349,7 +1349,7 @@ TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "a TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl|avxifma") TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_kunpckdi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kunpckdi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512bw,evex512") TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512bw,evex512") @@ -1665,56 +1665,56 @@ TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq TARGET_BUILTIN(__builtin_ia32_kaddqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kaddhi, "UsUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kaddsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kadddi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kadddi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kandqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kandsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kanddi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kanddi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kandnqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kandnsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kandndi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kandndi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_korqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_korsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kordi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kortestcqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kortestzqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kortestcsi, "iUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kortestzsi, "iUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iUOiUOi", "nc", "avx512bw,evex512") -TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iUOiUOi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ktestcqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestzqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestchi, "iUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestzhi, "iUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestcsi, "iUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ktestzsi, "iUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iUOiUOi", "nc", "avx512bw,evex512") -TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iUOiUOi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxnorqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxnorsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kxnordi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kxnordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kxorqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxorsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kxordi, "UOiUOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kxordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kshiftliqi, "UcUcIUi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kshiftlihi, "UsUsIUi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kshiftlisi, "UiUiIUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "UOiUOiIUi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "UOiUOiIUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kshiftriqi, "UcUcIUi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kshiftrihi, "UsUsIUi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kshiftrisi, "UiUiIUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kshiftridi, "UOiUOiIUi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kshiftridi, "UOiUOiIUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kmovb, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kmovw, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kmovd, "UiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kmovq, "UOiUOi", "nc", "avx512bw,evex512") +TARGET_BUILTIN(__builtin_ia32_kmovq, "UOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw,evex512") TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl") diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 085e316fcc671df86e8080d6641149e7f051ba92..28baa2e45e423e9d3839800bc1a22d03a5901f9c 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -88,6 +88,9 @@ clang_tablegen(arm_sve_typeflags.inc -gen-arm-sve-typeflags clang_tablegen(arm_sve_sema_rangechecks.inc -gen-arm-sve-sema-rangechecks SOURCE arm_sve.td TARGET ClangARMSveSemaRangeChecks) +clang_tablegen(arm_sve_streaming_attrs.inc -gen-arm-sve-streaming-attrs + SOURCE arm_sve.td + TARGET ClangARMSveStreamingAttrs) clang_tablegen(arm_sme_builtins.inc -gen-arm-sme-builtins SOURCE arm_sme.td TARGET ClangARMSmeBuiltins) @@ -97,6 +100,12 @@ clang_tablegen(arm_sme_builtin_cg.inc -gen-arm-sme-builtin-codegen clang_tablegen(arm_sme_sema_rangechecks.inc -gen-arm-sme-sema-rangechecks SOURCE arm_sme.td TARGET ClangARMSmeSemaRangeChecks) +clang_tablegen(arm_sme_streaming_attrs.inc -gen-arm-sme-streaming-attrs + SOURCE arm_sme.td + TARGET ClangARMSmeStreamingAttrs) +clang_tablegen(arm_sme_builtins_za_state.inc -gen-arm-sme-builtin-za-state + SOURCE arm_sme.td + TARGET ClangARMSmeBuiltinsZAState) clang_tablegen(arm_cde_builtins.inc -gen-arm-cde-builtin-def SOURCE arm_cde.td TARGET ClangARMCdeBuiltinsDef) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index caee2dc6daadb606dde10e47d2d5404081526d80..6765721ae7002c19ce7aa4206172cb244e25e863 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -40,6 +40,7 @@ def : DiagGroup<"auto-import">; def FrameworkHdrQuotedInclude : DiagGroup<"quoted-include-in-framework-header">; def FrameworkIncludePrivateFromPublic : DiagGroup<"framework-include-private-from-public">; +def DeprecatedModuleDotMap : DiagGroup<"deprecated-module-dot-map">; def FrameworkHdrAtImport : DiagGroup<"atimport-in-framework-header">; def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">; def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">; @@ -347,7 +348,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", CXXPre20CompatPedantic, CXXPre23CompatPedantic]>; -def CXX11Narrowing : DiagGroup<"c++11-narrowing">; +def CXX11NarrowingConstReference : DiagGroup<"c++11-narrowing-const-reference">; +def CXX11Narrowing : DiagGroup<"c++11-narrowing", [CXX11NarrowingConstReference]>; def CXX11WarnInconsistentOverrideDestructor : DiagGroup<"inconsistent-missing-destructor-override">; @@ -1487,4 +1489,5 @@ def DXILValidation : DiagGroup<"dxil-validation">; def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">; // Warnings and fixes to support the "safe buffers" programming model. -def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage">; +def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">; +def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer]>; diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 564ca48cc32ac558ea6a6cf1cc8c2972ab643536..75ca2fa16d34850f9342dadc2655972c878ac499 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -884,6 +884,9 @@ def warn_quoted_include_in_framework_header : Warning< def warn_framework_include_private_from_public : Warning< "public framework header includes private framework header '%0'" >, InGroup; +def warn_deprecated_module_dot_map : Warning< + "'%0' as a module map name is deprecated, rename it to %select{module.modulemap|module.private.modulemap}1%select{| in the 'Modules' directory of the framework}2">, + InGroup; def remark_pp_include_directive_modular_translation : Remark< "treating #%select{include|import|include_next|__include_macros}0 as an " diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6150fc36430ab16111148b25d725d69955e21842..e4b1069cde1850806014bc19378c6669000e3cee 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1358,11 +1358,9 @@ def err_acc_unexpected_directive def warn_pragma_acc_unimplemented : Warning<"OpenACC directives not yet implemented, pragma ignored">, InGroup; -def warn_pragma_acc_unimplemented_clause_parsing - : Warning<"OpenACC clause parsing not yet implemented">, - InGroup; def err_acc_invalid_directive : Error<"invalid OpenACC directive %select{%1|'%1 %2'}0">; +def err_acc_invalid_clause : Error<"invalid OpenACC clause %0">; def err_acc_missing_directive : Error<"expected OpenACC directive">; def err_acc_invalid_open_paren : Error<"expected clause-list or newline in OpenACC directive">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 94e97a891baedcdcbbfb02805d771201d82d8db4..aebb7d9b945c339d0d498dfb0e05438e07ec565f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3155,6 +3155,9 @@ def err_attribute_arm_feature_sve_bits_unsupported : Error< def warn_attribute_arm_sm_incompat_builtin : Warning< "builtin call has undefined behaviour when called from a %0 function">, InGroup>; +def warn_attribute_arm_za_builtin_no_za_state : Warning< + "builtin call is not valid when calling from a function without active ZA state">, + InGroup>; def err_sve_vector_in_non_sve_target : Error< "SVE vector type %0 cannot be used in a target without sve">; def err_attribute_riscv_rvv_bits_unsupported : Error< @@ -6155,12 +6158,24 @@ def err_illegal_initializer_type : Error<"illegal initializer type %0">; def ext_init_list_type_narrowing : ExtWarn< "type %0 cannot be narrowed to %1 in initializer list">, InGroup, DefaultError, SFINAEFailure; +// *_narrowing_const_reference diagnostics have the same messages, but are +// controlled by -Wc++11-narrowing-const-reference for narrowing involving a +// const reference. +def ext_init_list_type_narrowing_const_reference : ExtWarn< + "type %0 cannot be narrowed to %1 in initializer list">, + InGroup, DefaultError, SFINAEFailure; def ext_init_list_variable_narrowing : ExtWarn< "non-constant-expression cannot be narrowed from type %0 to %1 in " "initializer list">, InGroup, DefaultError, SFINAEFailure; +def ext_init_list_variable_narrowing_const_reference : ExtWarn< + "non-constant-expression cannot be narrowed from type %0 to %1 in " + "initializer list">, InGroup, DefaultError, SFINAEFailure; def ext_init_list_constant_narrowing : ExtWarn< "constant expression evaluates to %0 which cannot be narrowed to type %1">, InGroup, DefaultError, SFINAEFailure; +def ext_init_list_constant_narrowing_const_reference : ExtWarn< + "constant expression evaluates to %0 which cannot be narrowed to type %1">, + InGroup, DefaultError, SFINAEFailure; def warn_init_list_type_narrowing : Warning< "type %0 cannot be narrowed to %1 in initializer list in C++11">, InGroup, DefaultIgnore; @@ -6426,17 +6441,6 @@ def warn_superclass_variable_sized_type_not_at_end : Warning< "field %0 can overwrite instance variable %1 with variable sized type %2" " in superclass %3">, InGroup; -def err_counted_by_attr_not_on_flexible_array_member : Error< - "'counted_by' only applies to C99 flexible array members">; -def err_counted_by_attr_refers_to_flexible_array : Error< - "'counted_by' cannot refer to the flexible array %0">; -def err_counted_by_must_be_in_structure : Error< - "field %0 in 'counted_by' not inside structure">; -def err_flexible_array_counted_by_attr_field_not_integer : Error< - "field %0 in 'counted_by' must be a non-boolean integer type">; -def note_flexible_array_counted_by_attr_field : Note< - "field %0 declared here">; - let CategoryName = "ARC Semantic Issue" in { // ARC-mode diagnostics. @@ -8729,7 +8733,7 @@ def err_atomic_op_needs_atomic_int : Error< "address argument to atomic operation must be a pointer to " "%select{|atomic }0integer (%1 invalid)">; def warn_atomic_op_has_invalid_memory_order : Warning< - "memory order argument to atomic operation is invalid">, + "%select{|success |failure }0memory order argument to atomic operation is invalid">, InGroup>; def err_atomic_op_has_invalid_synch_scope : Error< "synchronization scope argument to atomic operation is invalid">; @@ -11368,6 +11372,8 @@ def err_openmp_vla_in_task_untied : Error< def warn_omp_unterminated_declare_target : Warning< "expected '#pragma omp end declare target' at end of file to match '#pragma omp %0'">, InGroup; +def err_ompx_bare_no_grid : Error< + "'ompx_bare' clauses requires explicit grid size via 'num_teams' and 'thread_limit' clauses">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 7473e00a7bd86bae6f92d4882070f2337a169c65..06efac0cf1abd7e7a529a9b7f3616b97eebb7010 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -282,7 +282,6 @@ EXTENSION(matrix_types_scalar_division, true) EXTENSION(cxx_attributes_on_using_declarations, LangOpts.CPlusPlus11) EXTENSION(datasizeof, LangOpts.CPlusPlus) -FEATURE(builtin_headers_in_system_modules, LangOpts.BuiltinHeadersInSystemModules) FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVTables) // CUDA/HIP Features diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index 0898e7d39dd7dee20301aa9926e66cefdfae7e0f..1ac182d4fce26f65f2179aaee96b4706bbb696ea 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -511,7 +511,7 @@ public: /// function(<#int x#>); /// \endcode bool isEditorPlaceholder() const { - return getName().startswith("<#") && getName().endswith("#>"); + return getName().starts_with("<#") && getName().ends_with("#>"); } /// Determine whether \p this is a name reserved for the implementation (C99 diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 152d9f65f86dbe022596239d664cc645a667ba79..21abc346cf17ac30e91d1d1a9e7518499b7452ec 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -456,6 +456,7 @@ ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAd ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, "Key used for return address signing") LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled") +LANGOPT(BranchProtectionPAuthLR, 1, 0, "Use PC as a diversifier using PAuthLR NOP instructions.") LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled") diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h index 62c0a4c1a9dea41f09b14335cdb6b7022a8a82d7..3117d584d347b968d28274ab514f3eb40cbc51b1 100644 --- a/clang/include/clang/Basic/OpenACCKinds.h +++ b/clang/include/clang/Basic/OpenACCKinds.h @@ -69,6 +69,30 @@ enum class OpenACCAtomicKind { Capture, Invalid, }; + +/// Represents the kind of an OpenACC clause. +enum class OpenACCClauseKind { + // 'finalize' clause, allowed on 'exit data' directive. + Finalize, + // 'if_present' clause, allowed on 'host_data' and 'update' directives. + IfPresent, + // 'seq' clause, allowed on 'loop' and 'routine' directives. + Seq, + // 'independent' clause, allowed on 'loop' directives. + Independent, + // 'auto' clause, allowed on 'loop' directives. + Auto, + // 'worker' clause, allowed on 'loop' and 'routine' directives. + Worker, + // 'vector' clause, allowed on 'loop' and 'routine' directives. Takes no + // arguments for 'routine', so the 'loop' version is not yet implemented + // completely. + Vector, + // 'nohost' clause, allowed on 'routine' directives. + NoHost, + // Represents an invalid clause, for the purposes of parsing. + Invalid, +}; } // namespace clang #endif // LLVM_CLANG_BASIC_OPENACCKINDS_H diff --git a/clang/include/clang/Basic/PlistSupport.h b/clang/include/clang/Basic/PlistSupport.h index 557462a5b90d01234ad4846e300b62d1bb167639..d52d196019cf84f881731f3b9249def9bde77584 100644 --- a/clang/include/clang/Basic/PlistSupport.h +++ b/clang/include/clang/Basic/PlistSupport.h @@ -77,8 +77,7 @@ inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) { inline raw_ostream &EmitString(raw_ostream &o, StringRef s) { o << ""; - for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { - char c = *I; + for (char c : s) { switch (c) { default: o << c; diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 8f7881abf26f7f49f5c71cec97248c166e6b5af5..c9f9cbec7493bfc91d21cf5f423ddb703252d86a 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -309,7 +309,7 @@ namespace clang { bool isTupleSet() const { return Flags & IsTupleSet; } bool isReadZA() const { return Flags & IsReadZA; } bool isWriteZA() const { return Flags & IsWriteZA; } - + bool isReductionQV() const { return Flags & IsReductionQV; } uint64_t getBits() const { return Flags; } bool isFlagSet(uint64_t Flag) const { return Flags & Flag; } }; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index ec0189627dfbd2c474803b19ae1ff5c45b6db9a6..ac3c324c6c29c482af7ab61db6ca23807f4d123b 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1372,6 +1372,7 @@ public: LangOptions::SignReturnAddressKeyKind SignKey = LangOptions::SignReturnAddressKeyKind::AKey; bool BranchTargetEnforcement = false; + bool BranchProtectionPAuthLR = false; }; /// Determine if the Architecture in this TargetInfo supports branch @@ -1423,6 +1424,8 @@ public: /// Identify whether this target supports IFuncs. bool supportsIFunc() const { + if (getTriple().isOSBinFormatMachO()) + return true; return getTriple().isOSBinFormatELF() && ((getTriple().isOSLinux() && !getTriple().isMusl()) || getTriple().isOSFreeBSD()); diff --git a/clang/include/clang/Basic/Version.h b/clang/include/clang/Basic/Version.h index 2881d8db954e0b18fd0a4e1819c74c8d0a21d1a1..8e4e6928fded504c992f49420bb03e29458bb1cd 100644 --- a/clang/include/clang/Basic/Version.h +++ b/clang/include/clang/Basic/Version.h @@ -40,6 +40,9 @@ namespace clang { /// string as getClangRevision. std::string getLLVMRevision(); + /// Retrieves the Clang vendor tag. + std::string getClangVendor(); + /// Retrieves the full repository version that is an amalgamation of /// the information in getClangRepositoryPath() and getClangRevision(). std::string getClangFullRepositoryVersion(); diff --git a/clang/include/clang/Basic/arm_sme.td b/clang/include/clang/Basic/arm_sme.td index fcff6fe35b7ba3f856d5b56ca05b5af1853d5c24..aac3bd486de9223327738526b57b0c693142458b 100644 --- a/clang/include/clang/Basic/arm_sme.td +++ b/clang/include/clang/Basic/arm_sme.td @@ -299,6 +299,44 @@ multiclass ZAAddSub { defm SVADD : ZAAddSub<"add">; defm SVSUB : ZAAddSub<"sub">; +// SME2 - MOVA + +// +// Single, 2 and 4 vector-group read/write intrinsics. +// + +multiclass ZAWrite_VG checks> { + def NAME # _VG2_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_hor_vg2", [IsSharedZA, IsStreaming], checks>; + def NAME # _VG2_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_ver_vg2", [IsSharedZA, IsStreaming], checks>; + def NAME # _VG4_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_hor_vg4", [IsSharedZA, IsStreaming], checks>; + def NAME # _VG4_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_ver_vg4", [IsSharedZA, IsStreaming], checks>; + def NAME # _VG1x2 : Inst<"svwrite_" # n # "[_{d}]_vg1x2", "vm2", t, MergeNone, i # "_vg1x2", [IsSharedZA, IsStreaming], []>; + def NAME # _VG1x4 : Inst<"svwrite_" # n # "[_{d}]_vg1x4", "vm4", t, MergeNone, i # "_vg1x4", [IsSharedZA, IsStreaming], []>; +} + +let TargetGuard = "sme2" in { + defm SVWRITE_ZA8 : ZAWrite_VG<"za8", "cUc", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>; + defm SVWRITE_ZA16 : ZAWrite_VG<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_1>]>; + defm SVWRITE_ZA32 : ZAWrite_VG<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>]>; + defm SVWRITE_ZA64 : ZAWrite_VG<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>]>; +} + +multiclass ZARead_VG checks> { + def NAME # _VG2_H : Inst<"svread_hor_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_hor_vg2", [IsSharedZA, IsPreservesZA, IsStreaming], checks>; + def NAME # _VG2_V : Inst<"svread_ver_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_ver_vg2", [IsSharedZA, IsPreservesZA, IsStreaming], checks>; + def NAME # _VG4_H : Inst<"svread_hor_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_hor_vg4", [IsSharedZA, IsPreservesZA, IsStreaming], checks>; + def NAME # _VG4_V : Inst<"svread_ver_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_ver_vg4", [IsSharedZA, IsPreservesZA, IsStreaming], checks>; + def NAME # _VG1x2 : Inst<"svread_" # n # "_{d}_vg1x2", "2m", t, MergeNone, i # "_vg1x2", [IsSharedZA, IsPreservesZA, IsStreaming], []>; + def NAME # _VG1x4 : Inst<"svread_" # n # "_{d}_vg1x4", "4m", t, MergeNone, i # "_vg1x4", [IsSharedZA, IsPreservesZA, IsStreaming], []>; +} + +let TargetGuard = "sme2" in { + defm SVREAD_ZA8 : ZARead_VG<"za8", "cUc", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_0>]>; + defm SVREAD_ZA16 : ZARead_VG<"za16", "sUshb", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_1>]>; + defm SVREAD_ZA32 : ZARead_VG<"za32", "iUif", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_3>]>; + defm SVREAD_ZA64 : ZARead_VG<"za64", "lUld", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_7>]>; +} + // // Outer product and accumulate/subtract // @@ -313,6 +351,285 @@ let TargetGuard = "sme2" in { def SVBMOPA : Inst<"svbmopa_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>; def SVBMOPS : Inst<"svbmops_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>; + + // VERTICAL DOT-PRODUCT + def SVVDOT_LANE_ZA32_VG1x2_S : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOT_LANE_ZA32_VG1x4_S : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOT_LANE_ZA32_VG1x2_U : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOT_LANE_ZA32_VG1x4_U : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOT_LANE_ZA32_VG1x2_F : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "hb", MergeNone, "aarch64_sme_fvdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVSUVDOT_LANE_ZA32_VG1x4 : Inst<"svsuvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_suvdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVUSVDOT_LANE_ZA32_VG1x4 : Inst<"svusvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_usvdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + + // Multi-vector signed & unsigned integer dot-product + def SVDOT_MULTI_ZA32_VG1x2_S : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA32_VG1x4_S : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA32_VG1x2_U : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA32_VG1x4_U : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA32_VG1x2_S : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA32_VG1x4_S : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA32_VG1x2_U : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA32_VG1x4_U : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_LANE_ZA32_VG1x2_S : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_ZA32_VG1x4_S : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_ZA32_VG1x2_U : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_ZA32_VG1x4_U : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + + def SVUSDOT_SINGLE_ZA32_VG1x2 : Inst<"svusdot[_single]_za32[_{d}]_vg1x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVUSDOT_SINGLE_ZA32_VG1x4 : Inst<"svusdot[_single]_za32[_{d}]_vg1x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVUSDOT_MULTI_ZA32_VG1x2 : Inst<"svusdot_za32[_{d}]_vg1x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVUSDOT_MULTI_ZA32_VG1x4 : Inst<"svusdot_za32[_{d}]_vg1x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVUSDOT_LANE_ZA32_VG1x2 : Inst<"svusdot_lane_za32[_{d}]_vg1x2", "vm2.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVUSDOT_LANE_ZA32_VG1x4 : Inst<"svusdot_lane_za32[_{d}]_vg1x4", "vm4.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + + def SVSUDOT_SINGLE_ZA32_VG1x2 : Inst<"svsudot[_single]_za32[_{d}]_vg1x2", "vm2.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVSUDOT_SINGLE_ZA32_VG1x4 : Inst<"svsudot[_single]_za32[_{d}]_vg1x4", "vm4.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + + // Multi-multi sudot builtins are mapped to usdot, with zn & zm operands swapped + def SVSUDOT_MULTI_ZA32_VG1x2 : Inst<"svsudot_za32[_{d}]_vg1x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVSUDOT_MULTI_ZA32_VG1x4 : Inst<"svsudot_za32[_{d}]_vg1x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + + def SVSUDOT_LANE_ZA32_VG1x2 : Inst<"svsudot_lane_za32[_{d}]_vg1x2", "vm2.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVSUDOT_LANE_ZA32_VG1x4 : Inst<"svsudot_lane_za32[_{d}]_vg1x4", "vm4.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + + // Multi-vector half-precision/BFloat16 floating-point dot-product + def SVDOT_MULTI_ZA32_VG1x2_F16 : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA32_VG1x4_F16 : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA32_VG1x2_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA32_VG1x4_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_LANE_ZA32_VG1x2_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_ZA32_VG1x4_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; +} + +let TargetGuard = "sme2,sme-i16i64" in { + def SVVDOT_LANE_ZA64_VG1x4_S : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_svdot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVVDOT_LANE_ZA64_VG1x4_U : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + + def SVDOT_MULTI_ZA64_VG1x2_S16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA64_VG1x4_S16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA64_VG1x2_U16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_MULTI_ZA64_VG1x4_U16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA64_VG1x2_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA64_VG1x4_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA64_VG1x2_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVDOT_SINGLE_ZA64_VG1x4_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVDOT_LANE_ZA64_VG1x2_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVDOT_LANE_ZA64_VG1x4_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVDOT_LANE_ZA64_VG1x2_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVDOT_LANE_ZA64_VG1x4_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; +} + +// FMLA/FMLS +let TargetGuard = "sme2" in { + def SVMLA_MULTI_VG1x2_F32 : Inst<"svmla_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLA_MULTI_VG1x4_F32 : Inst<"svmla_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVMLS_MULTI_VG1x2_F32 : Inst<"svmls_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLS_MULTI_VG1x4_F32 : Inst<"svmls_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsSharedZA], []>; + + def SVMLA_SINGLE_VG1x2_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLA_SINGLE_VG1x4_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVMLS_SINGLE_VG1x2_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLS_SINGLE_VG1x4_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsSharedZA], []>; + + def SVMLA_LANE_VG1x2_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVMLA_LANE_VG1x4_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVMLS_LANE_VG1x2_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVMLS_LANE_VG1x4_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>; +} + +let TargetGuard = "sme2,sme-f64f64" in { + def SVMLA_MULTI_VG1x2_F64 : Inst<"svmla_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLA_MULTI_VG1x4_F64 : Inst<"svmla_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVMLS_MULTI_VG1x2_F64 : Inst<"svmls_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLS_MULTI_VG1x4_F64 : Inst<"svmls_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsSharedZA], []>; + + def SVMLA_SINGLE_VG1x2_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLA_SINGLE_VG1x4_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsSharedZA], []>; + def SVMLS_SINGLE_VG1x2_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsSharedZA], []>; + def SVMLS_SINGLE_VG1x4_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsSharedZA], []>; + + def SVMLA_LANE_VG1x2_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVMLA_LANE_VG1x4_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVMLS_LANE_VG1x2_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; + def SVMLS_LANE_VG1x4_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>; +} + +// FMLAL/FMLSL/UMLAL/SMLAL +// SMLALL/UMLALL/USMLALL/SUMLALL +let TargetGuard = "sme2" in { + // MULTI MLAL + def SVMLAL_MULTI_VG2x2_F16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlal_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG2x4_F16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlal_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG2x2_S16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlal_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG2x4_S16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlal_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG2x2_U16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlal_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG2x4_U16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlal_vg2x4", [IsStreaming, IsSharedZA], []>; + + def SVMLAL_MULTI_VG4x2_S8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smla_za32_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG4x2_U8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG4x4_S8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smla_za32_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG4x4_U8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x4", [IsStreaming, IsSharedZA], []>; + + // MULTI MLSL + def SVMLSL_MULTI_VG2x2_F16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG2x4_F16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG2x2_S16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlsl_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG2x4_S16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlsl_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG2x2_U16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlsl_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG2x4_U16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlsl_vg2x4", [IsStreaming, IsSharedZA], []>; + + def SVMLSL_MULTI_VG4x2_S8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smls_za32_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG4x2_U8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG4x4_S8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smls_za32_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG4x4_U8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x4", [IsStreaming, IsSharedZA], []>; + + // SINGLE MLAL + def SVMLAL_SINGLE_VG2x1_F16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x2_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x4_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x1_S16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlal_single_vg2x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x2_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x4_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x1_U16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x2_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG2x4_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x4", [IsStreaming, IsSharedZA], []>; + + def SVMLAL_SINGLE_VG4x1_S8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x1_U8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x2_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x2_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x4_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x4_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>; + + // SINGLE MLSL + def SVMLSL_SINGLE_VG2x1_F16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x2_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x4_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x1_S16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x2_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x4_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x1_U16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x2_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG2x4_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x4", [IsStreaming, IsSharedZA], []>; + + def SVMLSL_SINGLE_VG4x1_S8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x1_U8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x2_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x2_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x4_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x4_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>; + + // INDEXED MLAL + def SVMLAL_LANE_VG2x1_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x2_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x4_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x1_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x2_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x4_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x1_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x2_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG2x4_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + + def SVMLAL_LANE_VG4x1_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLAL_LANE_VG4x1_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLAL_LANE_VG4x2_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLAL_LANE_VG4x2_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLAL_LANE_VG4x4_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLAL_LANE_VG4x4_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + + // INDEXED MLSL + def SVMLSL_LANE_VG2x1_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x2_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x4_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x1_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x2_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x4_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x1_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x2_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG2x4_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + + def SVMLSL_LANE_VG4x1_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLSL_LANE_VG4x1_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLSL_LANE_VG4x2_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLSL_LANE_VG4x2_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLSL_LANE_VG4x4_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLSL_LANE_VG4x4_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + + // SINGLE SUMLALL + // Single sumla maps to usmla, with zn & zm operands swapped + def SVSUMLALL_SINGLE_VG4x1 : Inst<"svsumla_za32[_{d}]_vg4x1", "vmdu", "c", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>; + + def SVSUMLALL_SINGLE_VG4x2 : Inst<"svsumla[_single]_za32[_{d}]_vg4x2", "vm2.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVSUMLALL_SINGLE_VG4x4 : Inst<"svsumla[_single]_za32[_{d}]_vg4x4", "vm4.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>; + + // Multi-multi sumla builtins are mapped to usmla, with zn & zm operands swapped + def SVSUMLALL_MULTI_VG4x2 : Inst<"svsumla_za32[_{d}]_vg4x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVSUMLALL_MULTI_VG4x4 : Inst<"svsumla_za32[_{d}]_vg4x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsSharedZA], []>; + + // INDEXED SUMLALL + def SVSUMLALL_LANE_VG4x1 : Inst<"svsumla_lane_za32[_{d}]_vg4x1", "vmdui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVSUMLALL_LANE_VG4x2 : Inst<"svsumla_lane_za32[_{d}]_vg4x2", "vm2ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVSUMLALL_LANE_VG4x4 : Inst<"svsumla_lane_za32[_{d}]_vg4x4", "vm4ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + + // SINGLE USMLALL + def SVUSMLALL_SINGLE_VG4x1 : Inst<"svusmla_za32[_{d}]_vg4x1", "vmdx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVUSMLALL_SINGLE_VG4x2 : Inst<"svusmla[_single]_za32[_{d}]_vg4x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVUSMLALL_SINGLE_VG4x4 : Inst<"svusmla[_single]_za32[_{d}]_vg4x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>; + + // MULTI USMLALL + def SVUSMLALL_MULTI_VG4x2 : Inst<"svusmla_za32[_{d}]_vg4x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVUSMLALL_MULTI_VG4x4 : Inst<"svusmla_za32[_{d}]_vg4x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsSharedZA], []>; + + // INDEXED USMLALL + def SVUSMLALL_LANE_VG4x1 : Inst<"svusmla_lane_za32[_{d}]_vg4x1", "vmdxi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVUSMLALL_LANE_VG4x2 : Inst<"svusmla_lane_za32[_{d}]_vg4x2", "vm2xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; + def SVUSMLALL_LANE_VG4x4 : Inst<"svusmla_lane_za32[_{d}]_vg4x4", "vm4xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>; +} + +let TargetGuard = "sme2,sme-i16i64" in { + // MULTI MLAL + def SVMLAL_MULTI_VG4x2_S16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smla_za64_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG4x2_U16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG4x4_S16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smla_za64_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_MULTI_VG4x4_U16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x4", [IsStreaming, IsSharedZA], []>; + + // MULTI MLSL + def SVMLSL_MULTI_VG4x2_S16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smls_za64_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG4x2_U16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG4x4_S16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smls_za64_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_MULTI_VG4x4_U16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x4", [IsStreaming, IsSharedZA], []>; + + // SINGLE MLAL + def SVMLAL_SINGLE_VG4x1_S16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x1_U16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x2_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x2_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x4_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLAL_SINGLE_VG4x4_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>; + + // SINGLE MLSL + def SVMLSL_SINGLE_VG4x1_S16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x1_U16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x2_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x2_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x4_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>; + def SVMLSL_SINGLE_VG4x4_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>; + + // INDEXED MLAL + def SVMLAL_LANE_VG4x1_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG4x1_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG4x2_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG4x2_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG4x4_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLAL_LANE_VG4x4_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + + // INDEXED MLSL + def SVMLSL_LANE_VG4x1_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG4x1_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG4x2_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG4x2_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG4x4_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; + def SVMLSL_LANE_VG4x4_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>; } // diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index aa9b105364a51a1004873c95e4dda5ac811268df..91f62c4c76339d00a905b468ee9706a77f35696c 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -19,27 +19,27 @@ include "arm_sve_sme_incl.td" // Loads // Load one vector (scalar base) -def SVLD1 : MInst<"svld1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; -def SVLD1SB : MInst<"svld1sb_{d}", "dPS", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ld1">; -def SVLD1UB : MInst<"svld1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1">; -def SVLD1SH : MInst<"svld1sh_{d}", "dPT", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ld1">; -def SVLD1UH : MInst<"svld1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1">; -def SVLD1SW : MInst<"svld1sw_{d}", "dPU", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1">; -def SVLD1UW : MInst<"svld1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1">; +def SVLD1 : MInst<"svld1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">; +def SVLD1SB : MInst<"svld1sb_{d}", "dPS", "silUsUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1UB : MInst<"svld1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1SH : MInst<"svld1sh_{d}", "dPT", "ilUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1UH : MInst<"svld1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1SW : MInst<"svld1sw_{d}", "dPU", "lUl", [IsLoad, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">; +def SVLD1UW : MInst<"svld1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">; let TargetGuard = "sve,bf16" in { - def SVLD1_BF : MInst<"svld1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; - def SVLD1_VNUM_BF : MInst<"svld1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; + def SVLD1_BF : MInst<"svld1[_{2}]", "dPc", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">; + def SVLD1_VNUM_BF : MInst<"svld1_vnum[_{2}]", "dPcl", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">; } // Load one vector (scalar base, VL displacement) -def SVLD1_VNUM : MInst<"svld1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; -def SVLD1SB_VNUM : MInst<"svld1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ld1">; -def SVLD1UB_VNUM : MInst<"svld1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1">; -def SVLD1SH_VNUM : MInst<"svld1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ld1">; -def SVLD1UH_VNUM : MInst<"svld1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1">; -def SVLD1SW_VNUM : MInst<"svld1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1">; -def SVLD1UW_VNUM : MInst<"svld1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1">; +def SVLD1_VNUM : MInst<"svld1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">; +def SVLD1SB_VNUM : MInst<"svld1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1UB_VNUM : MInst<"svld1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1SH_VNUM : MInst<"svld1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1UH_VNUM : MInst<"svld1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1SW_VNUM : MInst<"svld1sw_vnum_{d}", "dPUl", "lUl", [IsLoad, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">; +def SVLD1UW_VNUM : MInst<"svld1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">; // Load one vector (vector base) def SVLD1_GATHER_BASES_U : MInst<"svld1_gather[_{2}base]_{d}", "dPu", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_scalar_offset">; @@ -243,27 +243,27 @@ let TargetGuard = "sve,bf16" in { } // Load one vector, unextended load, non-temporal (scalar base) -def SVLDNT1 : MInst<"svldnt1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; +def SVLDNT1 : MInst<"svldnt1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">; // Load one vector, unextended load, non-temporal (scalar base, VL displacement) -def SVLDNT1_VNUM : MInst<"svldnt1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; +def SVLDNT1_VNUM : MInst<"svldnt1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">; let TargetGuard = "sve,bf16" in { - def SVLDNT1_BF : MInst<"svldnt1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; - def SVLDNT1_VNUM_BF : MInst<"svldnt1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; + def SVLDNT1_BF : MInst<"svldnt1[_{2}]", "dPc", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">; + def SVLDNT1_VNUM_BF : MInst<"svldnt1_vnum[_{2}]", "dPcl", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">; } // Load one quadword and replicate (scalar base) -def SVLD1RQ : SInst<"svld1rq[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1rq">; +def SVLD1RQ : SInst<"svld1rq[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1rq", [IsStreamingCompatible]>; let TargetGuard = "sve,bf16" in { - def SVLD1RQ_BF : SInst<"svld1rq[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1rq">; + def SVLD1RQ_BF : SInst<"svld1rq[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1rq", [IsStreamingCompatible]>; } multiclass StructLoad { - def : SInst; + def : SInst; let TargetGuard = "sve,bf16" in { - def: SInst; + def: SInst; } } @@ -286,16 +286,16 @@ let TargetGuard = "sve,f64mm,bf16" in { } let TargetGuard = "sve,bf16" in { - def SVBFDOT : SInst<"svbfdot[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone]>; - def SVBFMLALB : SInst<"svbfmlalb[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone]>; - def SVBFMLALT : SInst<"svbfmlalt[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone]>; - def SVBFMMLA : SInst<"svbfmmla[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmmla", [IsOverloadNone]>; - def SVBFDOT_N : SInst<"svbfdot[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone]>; - def SVBFMLAL_N : SInst<"svbfmlalb[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone]>; - def SVBFMLALT_N : SInst<"svbfmlalt[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone]>; - def SVBFDOT_LANE : SInst<"svbfdot_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfdot_lane_v2", [IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; - def SVBFMLALB_LANE : SInst<"svbfmlalb_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfmlalb_lane_v2", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; - def SVBFMLALT_LANE : SInst<"svbfmlalt_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfmlalt_lane_v2", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; + def SVBFDOT : SInst<"svbfdot[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFMLALB : SInst<"svbfmlalb[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFMLALT : SInst<"svbfmlalt[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFMMLA : SInst<"svbfmmla[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmmla", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFDOT_N : SInst<"svbfdot[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFMLAL_N : SInst<"svbfmlalb[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFMLALT_N : SInst<"svbfmlalt[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone, IsStreamingCompatible]>; + def SVBFDOT_LANE : SInst<"svbfdot_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfdot_lane_v2", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_3>]>; + def SVBFMLALB_LANE : SInst<"svbfmlalb_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfmlalb_lane_v2", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_7>]>; + def SVBFMLALT_LANE : SInst<"svbfmlalt_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfmlalt_lane_v2", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_7>]>; } let TargetGuard = "sve2p1" in { @@ -334,26 +334,26 @@ let TargetGuard = "sve2p1" in { // Stores // Store one vector (scalar base) -def SVST1 : MInst<"svst1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; -def SVST1B_S : MInst<"svst1b[_{d}]", "vPAd", "sil", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; -def SVST1B_U : MInst<"svst1b[_{d}]", "vPEd", "UsUiUl", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; -def SVST1H_S : MInst<"svst1h[_{d}]", "vPBd", "il", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; -def SVST1H_U : MInst<"svst1h[_{d}]", "vPFd", "UiUl", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; -def SVST1W_S : MInst<"svst1w[_{d}]", "vPCd", "l", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; -def SVST1W_U : MInst<"svst1w[_{d}]", "vPGd", "Ul", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; +def SVST1 : MInst<"svst1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">; +def SVST1B_S : MInst<"svst1b[_{d}]", "vPAd", "sil", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1B_U : MInst<"svst1b[_{d}]", "vPEd", "UsUiUl", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1H_S : MInst<"svst1h[_{d}]", "vPBd", "il", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1H_U : MInst<"svst1h[_{d}]", "vPFd", "UiUl", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1W_S : MInst<"svst1w[_{d}]", "vPCd", "l", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">; +def SVST1W_U : MInst<"svst1w[_{d}]", "vPGd", "Ul", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">; // Store one vector (scalar base, VL displacement) -def SVST1_VNUM : MInst<"svst1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; -def SVST1B_VNUM_S : MInst<"svst1b_vnum[_{d}]", "vPAld", "sil", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; -def SVST1B_VNUM_U : MInst<"svst1b_vnum[_{d}]", "vPEld", "UsUiUl", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; -def SVST1H_VNUM_S : MInst<"svst1h_vnum[_{d}]", "vPBld", "il", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; -def SVST1H_VNUM_U : MInst<"svst1h_vnum[_{d}]", "vPFld", "UiUl", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; -def SVST1W_VNUM_S : MInst<"svst1w_vnum[_{d}]", "vPCld", "l", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; -def SVST1W_VNUM_U : MInst<"svst1w_vnum[_{d}]", "vPGld", "Ul", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; +def SVST1_VNUM : MInst<"svst1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">; +def SVST1B_VNUM_S : MInst<"svst1b_vnum[_{d}]", "vPAld", "sil", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1B_VNUM_U : MInst<"svst1b_vnum[_{d}]", "vPEld", "UsUiUl", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1H_VNUM_S : MInst<"svst1h_vnum[_{d}]", "vPBld", "il", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1H_VNUM_U : MInst<"svst1h_vnum[_{d}]", "vPFld", "UiUl", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1W_VNUM_S : MInst<"svst1w_vnum[_{d}]", "vPCld", "l", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">; +def SVST1W_VNUM_U : MInst<"svst1w_vnum[_{d}]", "vPGld", "Ul", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">; let TargetGuard = "sve,bf16" in { - def SVST1_BF : MInst<"svst1[_{d}]", "vPpd", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; - def SVST1_VNUM_BF : MInst<"svst1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; + def SVST1_BF : MInst<"svst1[_{d}]", "vPpd", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">; + def SVST1_VNUM_BF : MInst<"svst1_vnum[_{d}]", "vPpld", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">; } // Store one vector (vector base) @@ -426,9 +426,9 @@ def SVST1H_SCATTER_INDEX_S : MInst<"svst1h_scatter[_{2}base]_index[_{d}]", "v def SVST1W_SCATTER_INDEX_S : MInst<"svst1w_scatter[_{2}base]_index[_{d}]", "vPuld", "lUl", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_scalar_offset">; multiclass StructStore { - def : SInst; + def : SInst; let TargetGuard = "sve,bf16" in { - def: SInst; + def: SInst; } } // Store N vectors into N-element structure (scalar base) @@ -442,14 +442,14 @@ defm SVST3_VNUM : StructStore<"svst3_vnum[_{d}]", "vPpl3", "aarch64_sve_st3">; defm SVST4_VNUM : StructStore<"svst4_vnum[_{d}]", "vPpl4", "aarch64_sve_st4">; // Store one vector, with no truncation, non-temporal (scalar base) -def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; +def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">; // Store one vector, with no truncation, non-temporal (scalar base, VL displacement) -def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; +def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">; let TargetGuard = "sve,bf16" in { - def SVSTNT1_BF : MInst<"svstnt1[_{d}]", "vPpd", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; - def SVSTNT1_VNUM_BF : MInst<"svstnt1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; + def SVSTNT1_BF : MInst<"svstnt1[_{d}]", "vPpd", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">; + def SVSTNT1_VNUM_BF : MInst<"svstnt1_vnum[_{d}]", "vPpld", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">; } let TargetGuard = "sve2p1" in { @@ -488,16 +488,16 @@ let TargetGuard = "sve2p1" in { // Prefetches // Prefetch (Scalar base) -def SVPRFB : MInst<"svprfb", "vPQJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">; -def SVPRFH : MInst<"svprfh", "vPQJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">; -def SVPRFW : MInst<"svprfw", "vPQJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">; -def SVPRFD : MInst<"svprfd", "vPQJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">; +def SVPRFB : MInst<"svprfb", "vPQJ", "c", [IsPrefetch, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_prf">; +def SVPRFH : MInst<"svprfh", "vPQJ", "s", [IsPrefetch, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_prf">; +def SVPRFW : MInst<"svprfw", "vPQJ", "i", [IsPrefetch, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_prf">; +def SVPRFD : MInst<"svprfd", "vPQJ", "l", [IsPrefetch, IsStreamingCompatible], MemEltTyInt64, "aarch64_sve_prf">; // Prefetch (Scalar base, VL displacement) -def SVPRFB_VNUM : MInst<"svprfb_vnum", "vPQlJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">; -def SVPRFH_VNUM : MInst<"svprfh_vnum", "vPQlJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">; -def SVPRFW_VNUM : MInst<"svprfw_vnum", "vPQlJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">; -def SVPRFD_VNUM : MInst<"svprfd_vnum", "vPQlJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">; +def SVPRFB_VNUM : MInst<"svprfb_vnum", "vPQlJ", "c", [IsPrefetch, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_prf">; +def SVPRFH_VNUM : MInst<"svprfh_vnum", "vPQlJ", "s", [IsPrefetch, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_prf">; +def SVPRFW_VNUM : MInst<"svprfw_vnum", "vPQlJ", "i", [IsPrefetch, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_prf">; +def SVPRFD_VNUM : MInst<"svprfd_vnum", "vPQlJ", "l", [IsPrefetch, IsStreamingCompatible], MemEltTyInt64, "aarch64_sve_prf">; // Prefetch (Vector bases) def SVPRFB_GATHER_BASES : MInst<"svprfb_gather[_{2}base]", "vPdJ", "UiUl", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_scalar_offset">; @@ -552,9 +552,9 @@ def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss", "iUif", MergeNone>; def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss", "lUld", MergeNone>; multiclass svdup_base { - def NAME : SInst; + def NAME : SInst; let TargetGuard = "sve,bf16" in { - def _BF16: SInst; + def _BF16: SInst; } } @@ -563,14 +563,14 @@ defm SVDUP_M : svdup_base<"svdup[_n]_{d}", "ddPs", MergeOp1, "aarch64_sve_du defm SVDUP_X : svdup_base<"svdup[_n]_{d}", "dPs", MergeAnyExp, "aarch64_sve_dup">; defm SVDUP_Z : svdup_base<"svdup[_n]_{d}", "dPs", MergeZeroExp, "aarch64_sve_dup">; -def SVINDEX : SInst<"svindex_{d}", "dss", "csilUcUsUiUl", MergeNone, "aarch64_sve_index">; +def SVINDEX : SInst<"svindex_{d}", "dss", "csilUcUsUiUl", MergeNone, "aarch64_sve_index", [IsStreamingCompatible]>; // Integer arithmetic -multiclass SInstZPZ flags=[]> { - def _M : SInst; - def _X : SInst; - def _Z : SInst; +multiclass SInstZPZ { + def _M : SInst; + def _X : SInst; + def _Z : SInst; } defm SVABS : SInstZPZ<"svabs", "csil", "aarch64_sve_abs">; @@ -579,13 +579,13 @@ defm SVNEG : SInstZPZ<"svneg", "csil", "aarch64_sve_neg">; //------------------------------------------------------------------------------ multiclass SInstZPZZ flags=[]> { - def _M : SInst; - def _X : SInst; - def _Z : SInst; + def _M : SInst; + def _X : SInst; + def _Z : SInst; - def _N_M : SInst; - def _N_X : SInst; - def _N_Z : SInst; + def _N_M : SInst; + def _N_X : SInst; + def _N_Z : SInst; } defm SVABD_S : SInstZPZZ<"svabd", "csil", "aarch64_sve_sabd", "aarch64_sve_sabd_u">; @@ -617,26 +617,26 @@ multiclass SInstZPZZZ; } -defm SVMAD : SInstZPZZZ<"svmad", "csilUcUsUiUl", "aarch64_sve_mad", "aarch64_sve_mla_u", [ReverseMergeAnyAccOp]>; -defm SVMLA : SInstZPZZZ<"svmla", "csilUcUsUiUl", "aarch64_sve_mla", "aarch64_sve_mla_u">; -defm SVMLS : SInstZPZZZ<"svmls", "csilUcUsUiUl", "aarch64_sve_mls", "aarch64_sve_mls_u">; -defm SVMSB : SInstZPZZZ<"svmsb", "csilUcUsUiUl", "aarch64_sve_msb", "aarch64_sve_mls_u", [ReverseMergeAnyAccOp]>; +defm SVMAD : SInstZPZZZ<"svmad", "csilUcUsUiUl", "aarch64_sve_mad", "aarch64_sve_mla_u", [ReverseMergeAnyAccOp, IsStreamingCompatible]>; +defm SVMLA : SInstZPZZZ<"svmla", "csilUcUsUiUl", "aarch64_sve_mla", "aarch64_sve_mla_u", [IsStreamingCompatible]>; +defm SVMLS : SInstZPZZZ<"svmls", "csilUcUsUiUl", "aarch64_sve_mls", "aarch64_sve_mls_u", [IsStreamingCompatible]>; +defm SVMSB : SInstZPZZZ<"svmsb", "csilUcUsUiUl", "aarch64_sve_msb", "aarch64_sve_mls_u", [ReverseMergeAnyAccOp, IsStreamingCompatible]>; //------------------------------------------------------------------------------ -def SVDOT_S : SInst<"svdot[_{0}]", "ddqq", "il", MergeNone, "aarch64_sve_sdot">; -def SVDOT_U : SInst<"svdot[_{0}]", "ddqq", "UiUl", MergeNone, "aarch64_sve_udot">; -def SVQADD_S : SInst<"svqadd[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqadd_x">; -def SVQADD_U : SInst<"svqadd[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x">; -def SVQSUB_S : SInst<"svqsub[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqsub_x">; -def SVQSUB_U : SInst<"svqsub[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x">; +def SVDOT_S : SInst<"svdot[_{0}]", "ddqq", "il", MergeNone, "aarch64_sve_sdot", [IsStreamingCompatible]>; +def SVDOT_U : SInst<"svdot[_{0}]", "ddqq", "UiUl", MergeNone, "aarch64_sve_udot", [IsStreamingCompatible]>; +def SVQADD_S : SInst<"svqadd[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqadd_x", [IsStreamingCompatible]>; +def SVQADD_U : SInst<"svqadd[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x", [IsStreamingCompatible]>; +def SVQSUB_S : SInst<"svqsub[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqsub_x", [IsStreamingCompatible]>; +def SVQSUB_U : SInst<"svqsub[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x", [IsStreamingCompatible]>; -def SVDOT_N_S : SInst<"svdot[_n_{0}]", "ddqr", "il", MergeNone, "aarch64_sve_sdot">; -def SVDOT_N_U : SInst<"svdot[_n_{0}]", "ddqr", "UiUl", MergeNone, "aarch64_sve_udot">; -def SVQADD_N_S : SInst<"svqadd[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqadd_x">; -def SVQADD_N_U : SInst<"svqadd[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x">; -def SVQSUB_N_S : SInst<"svqsub[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqsub_x">; -def SVQSUB_N_U : SInst<"svqsub[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x">; +def SVDOT_N_S : SInst<"svdot[_n_{0}]", "ddqr", "il", MergeNone, "aarch64_sve_sdot", [IsStreamingCompatible]>; +def SVDOT_N_U : SInst<"svdot[_n_{0}]", "ddqr", "UiUl", MergeNone, "aarch64_sve_udot", [IsStreamingCompatible]>; +def SVQADD_N_S : SInst<"svqadd[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqadd_x", [IsStreamingCompatible]>; +def SVQADD_N_U : SInst<"svqadd[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x", [IsStreamingCompatible]>; +def SVQSUB_N_S : SInst<"svqsub[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqsub_x", [IsStreamingCompatible]>; +def SVQSUB_N_U : SInst<"svqsub[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x", [IsStreamingCompatible]>; def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; @@ -656,107 +656,107 @@ defm SVNOT : SInstZPZ<"svnot", "csilUcUsUiUl", "aarch64_sve_not">; // Shifts multiclass SInst_SHIFT { - def _M : SInst; - def _X : SInst; - def _Z : SInst; + def _M : SInst; + def _X : SInst; + def _Z : SInst; - def _N_M : SInst; - def _N_X : SInst; - def _N_Z : SInst; + def _N_M : SInst; + def _N_X : SInst; + def _N_Z : SInst; - def _WIDE_M : SInst; - def _WIDE_X : SInst; - def _WIDE_Z : SInst; + def _WIDE_M : SInst; + def _WIDE_X : SInst; + def _WIDE_Z : SInst; - def _WIDE_N_M : SInst; - def _WIDE_N_X : SInst; - def _WIDE_N_Z : SInst; + def _WIDE_N_M : SInst; + def _WIDE_N_X : SInst; + def _WIDE_N_Z : SInst; } defm SVASR : SInst_SHIFT<"svasr", "aarch64_sve_asr", "csil", "csi">; defm SVLSL : SInst_SHIFT<"svlsl", "aarch64_sve_lsl", "csilUcUsUiUl", "csiUcUsUi">; defm SVLSR : SInst_SHIFT<"svlsr", "aarch64_sve_lsr", "UcUsUiUl", "UcUsUi">; -def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVASRD_X : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVASRD_Z : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_asrd", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVASRD_X : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_asrd", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVASRD_Z : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_asrd", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVINSR : SInst<"svinsr[_n_{d}]", "dds", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr">; +def SVINSR : SInst<"svinsr[_n_{d}]", "dds", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr", [IsStreamingCompatible]>; let TargetGuard = "sve,bf16" in { - def SVINSR_BF16 : SInst<"svinsr[_n_{d}]", "dds", "b", MergeNone, "aarch64_sve_insr">; + def SVINSR_BF16 : SInst<"svinsr[_n_{d}]", "dds", "b", MergeNone, "aarch64_sve_insr", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// // Integer reductions -def SVADDV_S : SInst<"svaddv[_{d}]", "lPd", "csil", MergeNone, "aarch64_sve_saddv">; -def SVADDV_U : SInst<"svaddv[_{d}]", "nPd", "UcUsUiUl", MergeNone, "aarch64_sve_uaddv">; -def SVANDV : SInst<"svandv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andv">; -def SVEORV : SInst<"sveorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorv">; -def SVMAXV_S : SInst<"svmaxv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_smaxv">; -def SVMAXV_U : SInst<"svmaxv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxv">; -def SVMINV_S : SInst<"svminv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_sminv">; -def SVMINV_U : SInst<"svminv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_uminv">; -def SVORV : SInst<"svorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orv">; +def SVADDV_S : SInst<"svaddv[_{d}]", "lPd", "csil", MergeNone, "aarch64_sve_saddv", [IsStreamingCompatible]>; +def SVADDV_U : SInst<"svaddv[_{d}]", "nPd", "UcUsUiUl", MergeNone, "aarch64_sve_uaddv", [IsStreamingCompatible]>; +def SVANDV : SInst<"svandv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andv", [IsStreamingCompatible]>; +def SVEORV : SInst<"sveorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorv", [IsStreamingCompatible]>; +def SVMAXV_S : SInst<"svmaxv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_smaxv", [IsStreamingCompatible]>; +def SVMAXV_U : SInst<"svmaxv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxv", [IsStreamingCompatible]>; +def SVMINV_S : SInst<"svminv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_sminv", [IsStreamingCompatible]>; +def SVMINV_U : SInst<"svminv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_uminv", [IsStreamingCompatible]>; +def SVORV : SInst<"svorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orv", [IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Integer comparisons -def SVCMPEQ : SInst<"svcmpeq[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq">; -def SVCMPNE : SInst<"svcmpne[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne">; -def SVCMPGE : SInst<"svcmpge[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge">; -def SVCMPGT : SInst<"svcmpgt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt">; -def SVCMPLE : SInst<"svcmple[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare]>; -def SVCMPLT : SInst<"svcmplt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare]>; -def SVCMPHI : SInst<"svcmpgt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi">; -def SVCMPHS : SInst<"svcmpge[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs">; -def SVCMPLO : SInst<"svcmplt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare]>; -def SVCMPLS : SInst<"svcmple[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare]>; - -def SVCMPEQ_N : SInst<"svcmpeq[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq">; -def SVCMPNE_N : SInst<"svcmpne[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne">; -def SVCMPGE_N : SInst<"svcmpge[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge">; -def SVCMPGT_N : SInst<"svcmpgt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt">; -def SVCMPLE_N : SInst<"svcmple[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare]>; -def SVCMPLT_N : SInst<"svcmplt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare]>; -def SVCMPHS_N : SInst<"svcmpge[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs">; -def SVCMPHI_N : SInst<"svcmpgt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi">; -def SVCMPLS_N : SInst<"svcmple[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare]>; -def SVCMPLO_N : SInst<"svcmplt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare]>; - -def SVCMPEQ_WIDE : SInst<"svcmpeq_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpeq_wide">; -def SVCMPNE_WIDE : SInst<"svcmpne_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpne_wide">; -def SVCMPGE_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpge_wide">; -def SVCMPGT_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpgt_wide">; -def SVCMPLE_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmple_wide">; -def SVCMPLT_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmplt_wide">; -def SVCMPHI_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide">; -def SVCMPHS_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide">; -def SVCMPLO_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide">; -def SVCMPLS_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide">; - -def SVCMPEQ_WIDE_N : SInst<"svcmpeq_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpeq_wide">; -def SVCMPNE_WIDE_N : SInst<"svcmpne_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpne_wide">; -def SVCMPGE_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpge_wide">; -def SVCMPGT_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpgt_wide">; -def SVCMPLE_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmple_wide">; -def SVCMPLT_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmplt_wide">; -def SVCMPHS_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide">; -def SVCMPHI_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide">; -def SVCMPLO_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide">; -def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide">; +def SVCMPEQ : SInst<"svcmpeq[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq", [IsStreamingCompatible]>; +def SVCMPNE : SInst<"svcmpne[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne", [IsStreamingCompatible]>; +def SVCMPGE : SInst<"svcmpge[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [IsStreamingCompatible]>; +def SVCMPGT : SInst<"svcmpgt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [IsStreamingCompatible]>; +def SVCMPLE : SInst<"svcmple[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPLT : SInst<"svcmplt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPHI : SInst<"svcmpgt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [IsStreamingCompatible]>; +def SVCMPHS : SInst<"svcmpge[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [IsStreamingCompatible]>; +def SVCMPLO : SInst<"svcmplt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPLS : SInst<"svcmple[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare, IsStreamingCompatible]>; + +def SVCMPEQ_N : SInst<"svcmpeq[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq", [IsStreamingCompatible]>; +def SVCMPNE_N : SInst<"svcmpne[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne", [IsStreamingCompatible]>; +def SVCMPGE_N : SInst<"svcmpge[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [IsStreamingCompatible]>; +def SVCMPGT_N : SInst<"svcmpgt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [IsStreamingCompatible]>; +def SVCMPLE_N : SInst<"svcmple[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPLT_N : SInst<"svcmplt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPHS_N : SInst<"svcmpge[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [IsStreamingCompatible]>; +def SVCMPHI_N : SInst<"svcmpgt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [IsStreamingCompatible]>; +def SVCMPLS_N : SInst<"svcmple[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPLO_N : SInst<"svcmplt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare, IsStreamingCompatible]>; + +def SVCMPEQ_WIDE : SInst<"svcmpeq_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpeq_wide", [IsStreamingCompatible]>; +def SVCMPNE_WIDE : SInst<"svcmpne_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpne_wide", [IsStreamingCompatible]>; +def SVCMPGE_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpge_wide", [IsStreamingCompatible]>; +def SVCMPGT_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpgt_wide", [IsStreamingCompatible]>; +def SVCMPLE_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmple_wide", [IsStreamingCompatible]>; +def SVCMPLT_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmplt_wide", [IsStreamingCompatible]>; +def SVCMPHI_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide", [IsStreamingCompatible]>; +def SVCMPHS_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide", [IsStreamingCompatible]>; +def SVCMPLO_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide", [IsStreamingCompatible]>; +def SVCMPLS_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide", [IsStreamingCompatible]>; + +def SVCMPEQ_WIDE_N : SInst<"svcmpeq_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpeq_wide", [IsStreamingCompatible]>; +def SVCMPNE_WIDE_N : SInst<"svcmpne_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpne_wide", [IsStreamingCompatible]>; +def SVCMPGE_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpge_wide", [IsStreamingCompatible]>; +def SVCMPGT_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpgt_wide", [IsStreamingCompatible]>; +def SVCMPLE_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmple_wide", [IsStreamingCompatible]>; +def SVCMPLT_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmplt_wide", [IsStreamingCompatible]>; +def SVCMPHS_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide", [IsStreamingCompatible]>; +def SVCMPHI_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide", [IsStreamingCompatible]>; +def SVCMPLO_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide", [IsStreamingCompatible]>; +def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide", [IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // While comparisons -def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile]>; -def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile]>; -def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile]>; -def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile]>; -def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile]>; -def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile]>; -def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile]>; -def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile]>; +def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile, IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Counting bit @@ -767,12 +767,12 @@ multiclass SInstCLS def _Z : SInst; } -defm SVCLS : SInstCLS<"svcls", "csil", "aarch64_sve_cls">; -defm SVCLZ : SInstCLS<"svclz", "csilUcUsUiUl", "aarch64_sve_clz">; -defm SVCNT : SInstCLS<"svcnt", "csilUcUsUiUlhfd", "aarch64_sve_cnt">; +defm SVCLS : SInstCLS<"svcls", "csil", "aarch64_sve_cls", [IsStreamingCompatible]>; +defm SVCLZ : SInstCLS<"svclz", "csilUcUsUiUl", "aarch64_sve_clz", [IsStreamingCompatible]>; +defm SVCNT : SInstCLS<"svcnt", "csilUcUsUiUlhfd", "aarch64_sve_cnt", [IsStreamingCompatible]>; let TargetGuard = "sve,bf16" in { - defm SVCNT_BF16 : SInstCLS<"svcnt", "b", "aarch64_sve_cnt">; + defm SVCNT_BF16 : SInstCLS<"svcnt", "b", "aarch64_sve_cnt", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// @@ -827,13 +827,13 @@ def SVTMAD : SInst<"svtmad[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_ftma def SVTSMUL : SInst<"svtsmul[_{d}]", "ddu", "hfd", MergeNone, "aarch64_sve_ftsmul_x">; def SVTSSEL : SInst<"svtssel[_{d}]", "ddu", "hfd", MergeNone, "aarch64_sve_ftssel_x">; -def SVSCALE_M : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeOp1, "aarch64_sve_fscale">; -def SVSCALE_X : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeAny, "aarch64_sve_fscale">; -def SVSCALE_Z : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeZero, "aarch64_sve_fscale">; +def SVSCALE_M : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeOp1, "aarch64_sve_fscale", [IsStreamingCompatible]>; +def SVSCALE_X : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeAny, "aarch64_sve_fscale", [IsStreamingCompatible]>; +def SVSCALE_Z : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeZero, "aarch64_sve_fscale", [IsStreamingCompatible]>; -def SVSCALE_N_M : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeOp1, "aarch64_sve_fscale">; -def SVSCALE_N_X : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeAny, "aarch64_sve_fscale">; -def SVSCALE_N_Z : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeZero, "aarch64_sve_fscale">; +def SVSCALE_N_M : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeOp1, "aarch64_sve_fscale", [IsStreamingCompatible]>; +def SVSCALE_N_X : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeAny, "aarch64_sve_fscale", [IsStreamingCompatible]>; +def SVSCALE_N_Z : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeZero, "aarch64_sve_fscale", [IsStreamingCompatible]>; defm SVMAD_F : SInstZPZZZ<"svmad", "hfd", "aarch64_sve_fmad", "aarch64_sve_fmla_u", [ReverseMergeAnyAccOp]>; defm SVMLA_F : SInstZPZZZ<"svmla", "hfd", "aarch64_sve_fmla", "aarch64_sve_fmla_u">; @@ -844,42 +844,42 @@ defm SVNMLA_F : SInstZPZZZ<"svnmla", "hfd", "aarch64_sve_fnmla", "aarch64_sve_fn defm SVNMLS_F : SInstZPZZZ<"svnmls", "hfd", "aarch64_sve_fnmls", "aarch64_sve_fnmls_u">; defm SVNMSB_F : SInstZPZZZ<"svnmsb", "hfd", "aarch64_sve_fnmsb", "aarch64_sve_fnmls_u", [ReverseMergeAnyAccOp]>; -def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; -def SVCADD_X : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeAny, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; -def SVCADD_Z : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeZero, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; -def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; -def SVCMLA_X : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeAny, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; -def SVCMLA_Z : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeZero, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCADD_X : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeAny, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCADD_Z : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeZero, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVCMLA_X : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeAny, "aarch64_sve_fcmla", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVCMLA_Z : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeZero, "aarch64_sve_fcmla", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>]>; -def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, +def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, ImmCheck<4, ImmCheckComplexRotAll90>]>; -def SVMLA_LANE : SInst<"svmla_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLS_LANE : SInst<"svmls_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMUL_LANE : SInst<"svmul_lane[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_fmul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMLA_LANE : SInst<"svmla_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLS_LANE : SInst<"svmls_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmls_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMUL_LANE : SInst<"svmul_lane[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_fmul_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVRECPE : SInst<"svrecpe[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frecpe_x">; -def SVRECPS : SInst<"svrecps[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frecps_x">; -def SVRSQRTE : SInst<"svrsqrte[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frsqrte_x">; -def SVRSQRTS : SInst<"svrsqrts[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frsqrts_x">; +def SVRECPE : SInst<"svrecpe[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frecpe_x", [IsStreamingCompatible]>; +def SVRECPS : SInst<"svrecps[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frecps_x", [IsStreamingCompatible]>; +def SVRSQRTE : SInst<"svrsqrte[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frsqrte_x", [IsStreamingCompatible]>; +def SVRSQRTS : SInst<"svrsqrts[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frsqrts_x", [IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Floating-point reductions -def SVFADDA : SInst<"svadda[_{d}]", "sPsd", "hfd", MergeNone, "aarch64_sve_fadda">; -def SVFADDV : SInst<"svaddv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_faddv">; -def SVFMAXV : SInst<"svmaxv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxv">; -def SVFMAXNMV : SInst<"svmaxnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxnmv">; -def SVFMINV : SInst<"svminv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminv">; -def SVFMINNMV : SInst<"svminnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminnmv">; +def SVFADDA : SInst<"svadda[_{d}]", "sPsd", "hfd", MergeNone, "aarch64_sve_fadda", [IsStreamingCompatible]>; +def SVFADDV : SInst<"svaddv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_faddv", [IsStreamingCompatible]>; +def SVFMAXV : SInst<"svmaxv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxv", [IsStreamingCompatible]>; +def SVFMAXNMV : SInst<"svmaxnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxnmv", [IsStreamingCompatible]>; +def SVFMINV : SInst<"svminv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminv", [IsStreamingCompatible]>; +def SVFMINNMV : SInst<"svminnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminnmv", [IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Floating-point comparisons -def SVACGE : SInst<"svacge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge">; -def SVACGT : SInst<"svacgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt">; -def SVACLE : SInst<"svacle[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare]>; -def SVACLT : SInst<"svaclt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>; -def SVCMPUO : SInst<"svcmpuo[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpuo">; +def SVACGE : SInst<"svacge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [IsStreamingCompatible]>; +def SVACGT : SInst<"svacgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [IsStreamingCompatible]>; +def SVACLE : SInst<"svacle[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare, IsStreamingCompatible]>; +def SVACLT : SInst<"svaclt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPUO : SInst<"svcmpuo[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpuo", [IsStreamingCompatible]>; def SVACGE_N : SInst<"svacge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge">; def SVACGT_N : SInst<"svacgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt">; @@ -887,19 +887,19 @@ def SVACLE_N : SInst<"svacle[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_ def SVACLT_N : SInst<"svaclt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>; def SVCMPUO_N : SInst<"svcmpuo[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpuo">; -def SVCMPEQ_F : SInst<"svcmpeq[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpeq">; -def SVCMPNE_F : SInst<"svcmpne[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpne">; -def SVCMPGE_F : SInst<"svcmpge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge">; -def SVCMPGT_F : SInst<"svcmpgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt">; -def SVCMPLE_F : SInst<"svcmple[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare]>; -def SVCMPLT_F : SInst<"svcmplt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare]>; +def SVCMPEQ_F : SInst<"svcmpeq[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpeq", [IsStreamingCompatible]>; +def SVCMPNE_F : SInst<"svcmpne[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpne", [IsStreamingCompatible]>; +def SVCMPGE_F : SInst<"svcmpge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [IsStreamingCompatible]>; +def SVCMPGT_F : SInst<"svcmpgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [IsStreamingCompatible]>; +def SVCMPLE_F : SInst<"svcmple[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPLT_F : SInst<"svcmplt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare, IsStreamingCompatible]>; -def SVCMPEQ_F_N : SInst<"svcmpeq[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpeq">; -def SVCMPNE_F_N : SInst<"svcmpne[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpne">; -def SVCMPGE_F_N : SInst<"svcmpge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge">; -def SVCMPGT_F_N : SInst<"svcmpgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt">; -def SVCMPLE_F_N : SInst<"svcmple[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare]>; -def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare]>; +def SVCMPEQ_F_N : SInst<"svcmpeq[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpeq", [IsStreamingCompatible]>; +def SVCMPNE_F_N : SInst<"svcmpne[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpne", [IsStreamingCompatible]>; +def SVCMPGE_F_N : SInst<"svcmpge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [IsStreamingCompatible]>; +def SVCMPGT_F_N : SInst<"svcmpgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [IsStreamingCompatible]>; +def SVCMPLE_F_N : SInst<"svcmple[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare, IsStreamingCompatible]>; +def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare, IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Floating-point conversions @@ -907,16 +907,16 @@ def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sv multiclass SInstCvtMXZ< string name, string m_types, string xz_types, string types, string intrinsic, list flags = [IsOverloadNone]> { - def _M : SInst; - def _X : SInst; - def _Z : SInst; + def _M : SInst; + def _X : SInst; + def _Z : SInst; } multiclass SInstCvtMX flags = [IsOverloadNone]> { - def _M : SInst; - def _X : SInst; + def _M : SInst; + def _X : SInst; } // svcvt_s##_f16 @@ -930,7 +930,7 @@ defm SVFCVTZS_S64_F32 : SInstCvtMXZ<"svcvt_s64[_f32]", "ddPM", "dPM", "l", "aar let TargetGuard = "sve,bf16" in { defm SVCVT_BF16_F32 : SInstCvtMXZ<"svcvt_bf16[_f32]", "ddPM", "dPM", "b", "aarch64_sve_fcvt_bf16f32">; - def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b", MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone]>; + def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b", MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone, IsStreamingCompatible]>; } // svcvt_s##_f64 @@ -994,11 +994,11 @@ defm SVCVTLT_F64 : SInstCvtMX<"svcvtlt_f64[_f32]", "ddPh", "dPh", "d", "aarc defm SVCVTX_F32 : SInstCvtMXZ<"svcvtx_f32[_f64]", "MMPd", "MPd", "d", "aarch64_sve_fcvtx_f32f64">; -def SVCVTNT_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone]>; -def SVCVTNT_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone]>; +def SVCVTNT_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone, IsStreamingCompatible]>; +def SVCVTNT_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone, IsStreamingCompatible]>; // SVCVTNT_X : Implemented as macro by SveEmitter.cpp -def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone]>; +def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone, IsStreamingCompatible]>; // SVCVTXNT_X_F32 : Implemented as macro by SveEmitter.cpp } @@ -1007,9 +1007,9 @@ def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch6 // Permutations and selection multiclass SVEPerm { - def : SInst; + def : SInst; let TargetGuard = "sve,bf16" in { - def: SInst; + def: SInst; } } @@ -1033,81 +1033,81 @@ def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfd", MergeNo let TargetGuard = "sve,bf16" in { def SVDUPQ_LANE_BF16 : SInst<"svdupq_lane[_{d}]", "ddn", "b", MergeNone, "aarch64_sve_dupq_lane">; } -def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>; +def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [IsStreamingCompatible], [ImmCheck<2, ImmCheckExtract, 1>]>; defm SVLASTA : SVEPerm<"svlasta[_{d}]", "sPd", "aarch64_sve_lasta">; defm SVLASTB : SVEPerm<"svlastb[_{d}]", "sPd", "aarch64_sve_lastb">; -def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_rev">; -def SVSEL : SInst<"svsel[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_sel">; -def SVSPLICE : SInst<"svsplice[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_splice">; -def SVTBL : SInst<"svtbl[_{d}]", "ddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">; +def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_rev", [IsStreamingCompatible]>; +def SVSEL : SInst<"svsel[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_sel", [IsStreamingCompatible]>; +def SVSPLICE : SInst<"svsplice[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_splice", [IsStreamingCompatible]>; +def SVTBL : SInst<"svtbl[_{d}]", "ddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>; let TargetGuard = "sve,bf16" in { - def SVTBL_BF16 : SInst<"svtbl[_{d}]", "ddu", "b", MergeNone, "aarch64_sve_tbl">; + def SVTBL_BF16 : SInst<"svtbl[_{d}]", "ddu", "b", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>; } -def SVTRN1 : SInst<"svtrn1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1">; -def SVTRN2 : SInst<"svtrn2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2">; -def SVUNPKHI_S : SInst<"svunpkhi[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpkhi">; -def SVUNPKHI_U : SInst<"svunpkhi[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpkhi">; -def SVUNPKLO_S : SInst<"svunpklo[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpklo">; -def SVUNPKLO_U : SInst<"svunpklo[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpklo">; -def SVUZP1 : SInst<"svuzp1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1">; -def SVUZP2 : SInst<"svuzp2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2">; -def SVZIP1 : SInst<"svzip1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1">; -def SVZIP2 : SInst<"svzip2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2">; +def SVTRN1 : SInst<"svtrn1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1", [IsStreamingCompatible]>; +def SVTRN2 : SInst<"svtrn2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2", [IsStreamingCompatible]>; +def SVUNPKHI_S : SInst<"svunpkhi[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpkhi", [IsStreamingCompatible]>; +def SVUNPKHI_U : SInst<"svunpkhi[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpkhi", [IsStreamingCompatible]>; +def SVUNPKLO_S : SInst<"svunpklo[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpklo", [IsStreamingCompatible]>; +def SVUNPKLO_U : SInst<"svunpklo[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpklo", [IsStreamingCompatible]>; +def SVUZP1 : SInst<"svuzp1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1", [IsStreamingCompatible]>; +def SVUZP2 : SInst<"svuzp2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2", [IsStreamingCompatible]>; +def SVZIP1 : SInst<"svzip1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1", [IsStreamingCompatible]>; +def SVZIP2 : SInst<"svzip2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2", [IsStreamingCompatible]>; let TargetGuard = "sve,bf16" in { -def SVEXT_BF16 : SInst<"svext[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>; -def SVREV_BF16 : SInst<"svrev[_{d}]", "dd", "b", MergeNone, "aarch64_sve_rev">; -def SVSEL_BF16 : SInst<"svsel[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_sel">; -def SVSPLICE_BF16 : SInst<"svsplice[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_splice">; -def SVTRN1_BF16 : SInst<"svtrn1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1">; -def SVTRN2_BF16 : SInst<"svtrn2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2">; -def SVUZP1_BF16 : SInst<"svuzp1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1">; -def SVUZP2_BF16 : SInst<"svuzp2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2">; -def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1">; -def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2">; -} - -def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "aarch64_sve_rev">; -def SVREV_B16 : SInst<"svrev_b16", "PP", "Pc", MergeNone, "aarch64_sve_rev_b16", [IsOverloadNone]>; -def SVREV_B32 : SInst<"svrev_b32", "PP", "Pc", MergeNone, "aarch64_sve_rev_b32", [IsOverloadNone]>; -def SVREV_B64 : SInst<"svrev_b64", "PP", "Pc", MergeNone, "aarch64_sve_rev_b64", [IsOverloadNone]>; -def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">; -def SVTRN1_B8 : SInst<"svtrn1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn1">; -def SVTRN1_B16 : SInst<"svtrn1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b16", [IsOverloadNone]>; -def SVTRN1_B32 : SInst<"svtrn1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b32", [IsOverloadNone]>; -def SVTRN1_B64 : SInst<"svtrn1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b64", [IsOverloadNone]>; -def SVTRN2_B8 : SInst<"svtrn2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn2">; -def SVTRN2_B16 : SInst<"svtrn2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b16", [IsOverloadNone]>; -def SVTRN2_B32 : SInst<"svtrn2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b32", [IsOverloadNone]>; -def SVTRN2_B64 : SInst<"svtrn2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b64", [IsOverloadNone]>; -def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">; -def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">; -def SVUZP1_B8 : SInst<"svuzp1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1">; -def SVUZP1_B16 : SInst<"svuzp1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b16", [IsOverloadNone]>; -def SVUZP1_B32 : SInst<"svuzp1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b32", [IsOverloadNone]>; -def SVUZP1_B64 : SInst<"svuzp1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b64", [IsOverloadNone]>; -def SVUZP2_B8 : SInst<"svuzp2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2">; -def SVUZP2_B16 : SInst<"svuzp2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b16", [IsOverloadNone]>; -def SVUZP2_B32 : SInst<"svuzp2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b32", [IsOverloadNone]>; -def SVUZP2_B64 : SInst<"svuzp2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b64", [IsOverloadNone]>; -def SVZIP1_B8 : SInst<"svzip1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip1">; -def SVZIP1_B16 : SInst<"svzip1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b16", [IsOverloadNone]>; -def SVZIP1_B32 : SInst<"svzip1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b32", [IsOverloadNone]>; -def SVZIP1_B64 : SInst<"svzip1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b64", [IsOverloadNone]>; -def SVZIP2_B : SInst<"svzip2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip2">; -def SVZIP2_B16 : SInst<"svzip2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b16", [IsOverloadNone]>; -def SVZIP2_B32 : SInst<"svzip2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b32", [IsOverloadNone]>; -def SVZIP2_B64 : SInst<"svzip2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b64", [IsOverloadNone]>; +def SVEXT_BF16 : SInst<"svext[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_ext", [IsStreamingCompatible], [ImmCheck<2, ImmCheckExtract, 1>]>; +def SVREV_BF16 : SInst<"svrev[_{d}]", "dd", "b", MergeNone, "aarch64_sve_rev", [IsStreamingCompatible]>; +def SVSEL_BF16 : SInst<"svsel[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_sel", [IsStreamingCompatible]>; +def SVSPLICE_BF16 : SInst<"svsplice[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_splice", [IsStreamingCompatible]>; +def SVTRN1_BF16 : SInst<"svtrn1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1", [IsStreamingCompatible]>; +def SVTRN2_BF16 : SInst<"svtrn2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2", [IsStreamingCompatible]>; +def SVUZP1_BF16 : SInst<"svuzp1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1", [IsStreamingCompatible]>; +def SVUZP2_BF16 : SInst<"svuzp2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2", [IsStreamingCompatible]>; +def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1", [IsStreamingCompatible]>; +def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2", [IsStreamingCompatible]>; +} + +def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "aarch64_sve_rev", [IsStreamingCompatible]>; +def SVREV_B16 : SInst<"svrev_b16", "PP", "Pc", MergeNone, "aarch64_sve_rev_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVREV_B32 : SInst<"svrev_b32", "PP", "Pc", MergeNone, "aarch64_sve_rev_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVREV_B64 : SInst<"svrev_b64", "PP", "Pc", MergeNone, "aarch64_sve_rev_b64", [IsOverloadNone, IsStreamingCompatible]>; +def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel", [IsStreamingCompatible]>; +def SVTRN1_B8 : SInst<"svtrn1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn1", [IsStreamingCompatible]>; +def SVTRN1_B16 : SInst<"svtrn1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVTRN1_B32 : SInst<"svtrn1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVTRN1_B64 : SInst<"svtrn1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b64", [IsOverloadNone, IsStreamingCompatible]>; +def SVTRN2_B8 : SInst<"svtrn2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn2", [IsStreamingCompatible]>; +def SVTRN2_B16 : SInst<"svtrn2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVTRN2_B32 : SInst<"svtrn2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVTRN2_B64 : SInst<"svtrn2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b64", [IsOverloadNone, IsStreamingCompatible]>; +def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi", [IsStreamingCompatible]>; +def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo", [IsStreamingCompatible]>; +def SVUZP1_B8 : SInst<"svuzp1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1", [IsStreamingCompatible]>; +def SVUZP1_B16 : SInst<"svuzp1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVUZP1_B32 : SInst<"svuzp1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVUZP1_B64 : SInst<"svuzp1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b64", [IsOverloadNone, IsStreamingCompatible]>; +def SVUZP2_B8 : SInst<"svuzp2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2", [IsStreamingCompatible]>; +def SVUZP2_B16 : SInst<"svuzp2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVUZP2_B32 : SInst<"svuzp2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVUZP2_B64 : SInst<"svuzp2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b64", [IsOverloadNone, IsStreamingCompatible]>; +def SVZIP1_B8 : SInst<"svzip1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip1", [IsStreamingCompatible]>; +def SVZIP1_B16 : SInst<"svzip1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVZIP1_B32 : SInst<"svzip1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVZIP1_B64 : SInst<"svzip1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b64", [IsOverloadNone, IsStreamingCompatible]>; +def SVZIP2_B : SInst<"svzip2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip2", [IsStreamingCompatible]>; +def SVZIP2_B16 : SInst<"svzip2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b16", [IsOverloadNone, IsStreamingCompatible]>; +def SVZIP2_B32 : SInst<"svzip2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b32", [IsOverloadNone, IsStreamingCompatible]>; +def SVZIP2_B64 : SInst<"svzip2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b64", [IsOverloadNone, IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Predicate creation -def SVPFALSE : SInst<"svpfalse[_b]", "Pv", "", MergeNone, "", [IsOverloadNone]>; +def SVPFALSE : SInst<"svpfalse[_b]", "Pv", "", MergeNone, "", [IsOverloadNone, IsStreamingCompatible]>; -def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue">; -def SVPTRUE : SInst<"svptrue_{d}", "Pv", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL]>; +def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsStreamingCompatible]>; +def SVPTRUE : SInst<"svptrue_{d}", "Pv", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL, IsStreamingCompatible]>; def SVDUPQ_B8 : SInst<"svdupq[_n]_{d}", "Pssssssssssssssss", "Pc", MergeNone>; def SVDUPQ_B16 : SInst<"svdupq[_n]_{d}", "Pssssssss", "Ps", MergeNone>; @@ -1119,33 +1119,33 @@ def SVDUP_N_B : SInst<"svdup[_n]_{d}", "Ps", "PcPsPiPl", MergeNone>; //////////////////////////////////////////////////////////////////////////////// // Predicate operations -def SVAND_B_Z : SInst<"svand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_and_z">; -def SVBIC_B_Z : SInst<"svbic[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_bic_z">; -def SVEOR_B_Z : SInst<"sveor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_eor_z">; -def SVMOV_B_Z : SInst<"svmov[_b]_z", "PPP", "Pc", MergeNone>; // Uses custom expansion -def SVNAND_B_Z : SInst<"svnand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nand_z">; -def SVNOR_B_Z : SInst<"svnor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nor_z">; -def SVNOT_B_Z : SInst<"svnot[_b]_z", "PPP", "Pc", MergeNone>; // Uses custom expansion -def SVORN_B_Z : SInst<"svorn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orn_z">; -def SVORR_B_Z : SInst<"svorr[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orr_z">; - -def SVBRKA : SInst<"svbrka[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brka">; -def SVBRKA_Z : SInst<"svbrka[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brka_z">; -def SVBRKB : SInst<"svbrkb[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brkb">; -def SVBRKB_Z : SInst<"svbrkb[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brkb_z">; -def SVBRKN_Z : SInst<"svbrkn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkn_z">; -def SVBRKPA_Z : SInst<"svbrkpa[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpa_z">; -def SVBRKPB_Z : SInst<"svbrkpb[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpb_z">; - -def SVPFIRST : SInst<"svpfirst[_b]", "PPP", "Pc", MergeNone, "aarch64_sve_pfirst">; -def SVPNEXT : SInst<"svpnext_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_pnext">; +def SVAND_B_Z : SInst<"svand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_and_z", [IsStreamingCompatible]>; +def SVBIC_B_Z : SInst<"svbic[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_bic_z", [IsStreamingCompatible]>; +def SVEOR_B_Z : SInst<"sveor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_eor_z", [IsStreamingCompatible]>; +def SVMOV_B_Z : SInst<"svmov[_b]_z", "PPP", "Pc", MergeNone, "", [IsStreamingCompatible]>; // Uses custom expansion +def SVNAND_B_Z : SInst<"svnand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nand_z", [IsStreamingCompatible]>; +def SVNOR_B_Z : SInst<"svnor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nor_z", [IsStreamingCompatible]>; +def SVNOT_B_Z : SInst<"svnot[_b]_z", "PPP", "Pc", MergeNone, "", [IsStreamingCompatible]>; // Uses custom expansion +def SVORN_B_Z : SInst<"svorn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orn_z", [IsStreamingCompatible]>; +def SVORR_B_Z : SInst<"svorr[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orr_z", [IsStreamingCompatible]>; + +def SVBRKA : SInst<"svbrka[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brka", [IsStreamingCompatible]>; +def SVBRKA_Z : SInst<"svbrka[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brka_z", [IsStreamingCompatible]>; +def SVBRKB : SInst<"svbrkb[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brkb", [IsStreamingCompatible]>; +def SVBRKB_Z : SInst<"svbrkb[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brkb_z", [IsStreamingCompatible]>; +def SVBRKN_Z : SInst<"svbrkn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkn_z", [IsStreamingCompatible]>; +def SVBRKPA_Z : SInst<"svbrkpa[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpa_z", [IsStreamingCompatible]>; +def SVBRKPB_Z : SInst<"svbrkpb[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpb_z", [IsStreamingCompatible]>; + +def SVPFIRST : SInst<"svpfirst[_b]", "PPP", "Pc", MergeNone, "aarch64_sve_pfirst", [IsStreamingCompatible]>; +def SVPNEXT : SInst<"svpnext_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_pnext", [IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // Testing predicates -def SVPTEST_ANY : SInst<"svptest_any", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_any">; -def SVPTEST_FIRST : SInst<"svptest_first", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_first">; -def SVPTEST_LAST : SInst<"svptest_last", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_last">; +def SVPTEST_ANY : SInst<"svptest_any", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_any", [IsStreamingCompatible]>; +def SVPTEST_FIRST : SInst<"svptest_first", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_first", [IsStreamingCompatible]>; +def SVPTEST_LAST : SInst<"svptest_last", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_last", [IsStreamingCompatible]>; //////////////////////////////////////////////////////////////////////////////// // FFR manipulation @@ -1158,21 +1158,21 @@ def SVWRFFR : SInst<"svwrffr", "vP", "Pc", MergeNone, "", [IsOverloadNone]>; //////////////////////////////////////////////////////////////////////////////// // Counting elements -def SVCNTB_PAT : SInst<"svcntb_pat", "nI", "", MergeNone, "aarch64_sve_cntb", [IsOverloadNone]>; -def SVCNTH_PAT : SInst<"svcnth_pat", "nI", "", MergeNone, "aarch64_sve_cnth", [IsOverloadNone]>; -def SVCNTW_PAT : SInst<"svcntw_pat", "nI", "", MergeNone, "aarch64_sve_cntw", [IsOverloadNone]>; -def SVCNTD_PAT : SInst<"svcntd_pat", "nI", "", MergeNone, "aarch64_sve_cntd", [IsOverloadNone]>; +def SVCNTB_PAT : SInst<"svcntb_pat", "nI", "", MergeNone, "aarch64_sve_cntb", [IsOverloadNone, IsStreamingCompatible]>; +def SVCNTH_PAT : SInst<"svcnth_pat", "nI", "", MergeNone, "aarch64_sve_cnth", [IsOverloadNone, IsStreamingCompatible]>; +def SVCNTW_PAT : SInst<"svcntw_pat", "nI", "", MergeNone, "aarch64_sve_cntw", [IsOverloadNone, IsStreamingCompatible]>; +def SVCNTD_PAT : SInst<"svcntd_pat", "nI", "", MergeNone, "aarch64_sve_cntd", [IsOverloadNone, IsStreamingCompatible]>; -def SVCNTB : SInst<"svcntb", "nv", "", MergeNone, "aarch64_sve_cntb", [IsAppendSVALL, IsOverloadNone]>; -def SVCNTH : SInst<"svcnth", "nv", "", MergeNone, "aarch64_sve_cnth", [IsAppendSVALL, IsOverloadNone]>; -def SVCNTW : SInst<"svcntw", "nv", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone]>; -def SVCNTD : SInst<"svcntd", "nv", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone]>; +def SVCNTB : SInst<"svcntb", "nv", "", MergeNone, "aarch64_sve_cntb", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>; +def SVCNTH : SInst<"svcnth", "nv", "", MergeNone, "aarch64_sve_cnth", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>; +def SVCNTW : SInst<"svcntw", "nv", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>; +def SVCNTD : SInst<"svcntd", "nv", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>; -def SVCNTP : SInst<"svcntp_{d}", "nPP", "PcPsPiPl", MergeNone, "aarch64_sve_cntp">; -def SVLEN : SInst<"svlen[_{d}]", "nd", "csilUcUsUiUlhfd", MergeNone>; +def SVCNTP : SInst<"svcntp_{d}", "nPP", "PcPsPiPl", MergeNone, "aarch64_sve_cntp", [IsStreamingCompatible]>; +def SVLEN : SInst<"svlen[_{d}]", "nd", "csilUcUsUiUlhfd", MergeNone, "", [IsStreamingCompatible]>; let TargetGuard = "sve,bf16" in { -def SVLEN_BF16 : SInst<"svlen[_{d}]", "nd", "b", MergeNone>; +def SVLEN_BF16 : SInst<"svlen[_{d}]", "nd", "b", MergeNone, "", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1189,20 +1189,20 @@ def UnsignedWord : sat_type<"U", "Ui">; def UnsignedDoubleWord : sat_type<"U", "Ul">; multiclass SInst_SAT1 { - def _N32 : SInst]>; - def _N64 : SInst]>; - def _N32_ALL : SInst]>; - def _N64_ALL : SInst]>; + def _N32 : SInst]>; + def _N64 : SInst]>; + def _N32_ALL : SInst]>; + def _N64_ALL : SInst]>; } multiclass SInst_SAT2 { - def "" : SInst]>; - def _ALL : SInst]>; + def "" : SInst]>; + def _ALL : SInst]>; - def _N32 : SInst]>; - def _N64 : SInst]>; - def _N32_ALL : SInst]>; - def _N64_ALL : SInst]>; + def _N32 : SInst]>; + def _N64 : SInst]>; + def _N32_ALL : SInst]>; + def _N64_ALL : SInst]>; } defm SVQDECB_S : SInst_SAT1<"svqdecb", "aarch64_sve_sqdecb", SignedByte>; @@ -1223,32 +1223,32 @@ defm SVQINCW_U : SInst_SAT2<"svqincw", "aarch64_sve_uqincw", UnsignedWord>; defm SVQINCD_S : SInst_SAT2<"svqincd", "aarch64_sve_sqincd", SignedDoubleWord>; defm SVQINCD_U : SInst_SAT2<"svqincd", "aarch64_sve_uqincd", UnsignedDoubleWord>; -def SVQDECP_S : SInst<"svqdecp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqdecp">; -def SVQDECP_U : SInst<"svqdecp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqdecp">; -def SVQINCP_S : SInst<"svqincp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqincp">; -def SVQINCP_U : SInst<"svqincp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqincp">; +def SVQDECP_S : SInst<"svqdecp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqdecp", [IsStreamingCompatible]>; +def SVQDECP_U : SInst<"svqdecp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqdecp", [IsStreamingCompatible]>; +def SVQINCP_S : SInst<"svqincp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqincp", [IsStreamingCompatible]>; +def SVQINCP_U : SInst<"svqincp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqincp", [IsStreamingCompatible]>; -def SVQDECP_N_S32 : SInst<"svqdecp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n32">; -def SVQDECP_N_S64 : SInst<"svqdecp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n64">; -def SVQDECP_N_U32 : SInst<"svqdecp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n32">; -def SVQDECP_N_U64 : SInst<"svqdecp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n64">; -def SVQINCP_N_S32 : SInst<"svqincp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n32">; -def SVQINCP_N_S64 : SInst<"svqincp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n64">; -def SVQINCP_N_U32 : SInst<"svqincp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n32">; -def SVQINCP_N_U64 : SInst<"svqincp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n64">; +def SVQDECP_N_S32 : SInst<"svqdecp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n32", [IsStreamingCompatible]>; +def SVQDECP_N_S64 : SInst<"svqdecp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n64", [IsStreamingCompatible]>; +def SVQDECP_N_U32 : SInst<"svqdecp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n32", [IsStreamingCompatible]>; +def SVQDECP_N_U64 : SInst<"svqdecp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n64", [IsStreamingCompatible]>; +def SVQINCP_N_S32 : SInst<"svqincp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n32", [IsStreamingCompatible]>; +def SVQINCP_N_S64 : SInst<"svqincp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n64", [IsStreamingCompatible]>; +def SVQINCP_N_U32 : SInst<"svqincp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n32", [IsStreamingCompatible]>; +def SVQINCP_N_U64 : SInst<"svqincp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n64", [IsStreamingCompatible]>; let TargetGuard = "sve,i8mm" in { def SVMLLA_S32 : SInst<"svmmla[_s32]", "ddqq","i", MergeNone, "aarch64_sve_smmla">; def SVMLLA_U32 : SInst<"svmmla[_u32]", "ddqq","Ui", MergeNone, "aarch64_sve_ummla">; def SVUSMLLA_S32 : SInst<"svusmmla[_s32]", "ddbq","i", MergeNone, "aarch64_sve_usmmla">; -def SVUSDOT_S : SInst<"svusdot[_s32]", "ddbq", "i", MergeNone, "aarch64_sve_usdot">; -def SVUSDOT_N_S : SInst<"svusdot[_n_s32]", "ddbr", "i", MergeNone, "aarch64_sve_usdot">; -def SVSUDOT_S : SInst<"svsudot[_s32]", "ddqb", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT]>; -def SVSUDOT_N_S : SInst<"svsudot[_n_s32]", "ddq@", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT]>; +def SVUSDOT_S : SInst<"svusdot[_s32]", "ddbq", "i", MergeNone, "aarch64_sve_usdot", [IsStreamingCompatible]>; +def SVUSDOT_N_S : SInst<"svusdot[_n_s32]", "ddbr", "i", MergeNone, "aarch64_sve_usdot", [IsStreamingCompatible]>; +def SVSUDOT_S : SInst<"svsudot[_s32]", "ddqb", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT, IsStreamingCompatible]>; +def SVSUDOT_N_S : SInst<"svsudot[_n_s32]", "ddq@", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT, IsStreamingCompatible]>; -def SVUSDOT_LANE_S : SInst<"svusdot_lane[_s32]", "ddbqi", "i", MergeNone, "aarch64_sve_usdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; -def SVSUDOT_LANE_S : SInst<"svsudot_lane[_s32]", "ddqbi", "i", MergeNone, "aarch64_sve_sudot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +def SVUSDOT_LANE_S : SInst<"svusdot_lane[_s32]", "ddbqi", "i", MergeNone, "aarch64_sve_usdot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +def SVSUDOT_LANE_S : SInst<"svsudot_lane[_s32]", "ddqbi", "i", MergeNone, "aarch64_sve_sudot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; } let TargetGuard = "sve,f32mm" in { @@ -1257,12 +1257,12 @@ def SVMLLA_F32 : SInst<"svmmla[_f32]", "dddd","f", MergeNone, "aarch64_sve_fmmla let TargetGuard = "sve,f64mm" in { def SVMLLA_F64 : SInst<"svmmla[_f64]", "dddd","d", MergeNone, "aarch64_sve_fmmla">; -def SVTRN1Q : SInst<"svtrn1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1q">; -def SVTRN2Q : SInst<"svtrn2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2q">; -def SVUZP1Q : SInst<"svuzp1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1q">; -def SVUZP2Q : SInst<"svuzp2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2q">; -def SVZIP1Q : SInst<"svzip1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1q">; -def SVZIP2Q : SInst<"svzip2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2q">; +def SVTRN1Q : SInst<"svtrn1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1q", [IsStreamingCompatible]>; +def SVTRN2Q : SInst<"svtrn2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2q", [IsStreamingCompatible]>; +def SVUZP1Q : SInst<"svuzp1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1q", [IsStreamingCompatible]>; +def SVUZP2Q : SInst<"svuzp2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2q", [IsStreamingCompatible]>; +def SVZIP1Q : SInst<"svzip1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1q", [IsStreamingCompatible]>; +def SVZIP2Q : SInst<"svzip2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2q", [IsStreamingCompatible]>; } let TargetGuard = "sve,bf16,f64mm" in { @@ -1276,20 +1276,20 @@ def SVZIP2Q_BF16 : SInst<"svzip2q[_{d}]", "ddd", "b", MergeNone, "aarc //////////////////////////////////////////////////////////////////////////////// // Vector creation -def SVUNDEF_1 : SInst<"svundef_{d}", "dv", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; -def SVUNDEF_2 : SInst<"svundef2_{d}", "2v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; -def SVUNDEF_3 : SInst<"svundef3_{d}", "3v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; -def SVUNDEF_4 : SInst<"svundef4_{d}", "4v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; +def SVUNDEF_1 : SInst<"svundef_{d}", "dv", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>; +def SVUNDEF_2 : SInst<"svundef2_{d}", "2v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>; +def SVUNDEF_3 : SInst<"svundef3_{d}", "3v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>; +def SVUNDEF_4 : SInst<"svundef4_{d}", "4v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>; def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate]>; def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate]>; def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate]>; let TargetGuard = "sve,bf16" in { -def SVUNDEF_1_BF16 : SInst<"svundef_{d}", "dv", "b", MergeNone, "", [IsUndef]>; -def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2v", "b", MergeNone, "", [IsUndef]>; -def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3v", "b", MergeNone, "", [IsUndef]>; -def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4v", "b", MergeNone, "", [IsUndef]>; +def SVUNDEF_1_BF16 : SInst<"svundef_{d}", "dv", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>; +def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>; +def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>; +def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>; def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd", "b", MergeNone, "", [IsTupleCreate]>; def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "", [IsTupleCreate]>; @@ -1331,14 +1331,26 @@ let TargetGuard = "sve2p1" in { //////////////////////////////////////////////////////////////////////////////// // SVE2 WhileGE/GT let TargetGuard = "sve2" in { -def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile]>; -def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile]>; -def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile]>; -def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile]>; -def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile]>; -def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile]>; -def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile]>; -def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile]>; +def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile, IsStreamingCompatible]>; +def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile, IsStreamingCompatible]>; +} + +let TargetGuard = "sve2p1|sme2" in { + def SVWHILEGE_S64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege_x2">; + def SVWHILEGT_S64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt_x2">; + def SVWHILEHI_U64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehi_x2">; + def SVWHILEHS_U64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehs_x2">; + def SVWHILELE_S64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele_x2">; + def SVWHILELT_S64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt_x2">; + def SVWHILELO_U64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilelo_x2">; + def SVWHILELS_U64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilels_x2">; + } //////////////////////////////////////////////////////////////////////////////// @@ -1380,49 +1392,49 @@ multiclass SInstZPZxZ; -defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl">; -defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl">; -defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl">; -defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl">; -defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl">; -defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd">; -defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd">; - -def SVABA_S : SInst<"svaba[_{d}]", "dddd", "csil" , MergeNone, "aarch64_sve_saba">; -def SVABA_U : SInst<"svaba[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uaba">; -def SVQDMULH : SInst<"svqdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqdmulh">; -def SVQRDMULH : SInst<"svqrdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqrdmulh">; -def SVQRDMLAH : SInst<"svqrdmlah[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlah">; -def SVQRDMLSH : SInst<"svqrdmlsh[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlsh">; - -def SVABA_S_N : SInst<"svaba[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_saba">; -def SVABA_U_N : SInst<"svaba[_n_{d}]", "ddda", "UcUsUiUl", MergeNone, "aarch64_sve_uaba">; -def SVQDMULH_N : SInst<"svqdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqdmulh">; -def SVQRDMULH_N : SInst<"svqrdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqrdmulh">; -def SVQRDMLAH_N : SInst<"svqrdmlah[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlah">; -def SVQRDMLSH_N : SInst<"svqrdmlsh[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlsh">; - -def SVQDMULH_LANE : SInst<"svqdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqdmulh_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVQRDMULH_LANE : SInst<"svqrdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqrdmulh_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVQRDMLAH_LANE : SInst<"svqrdmlah_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlah_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVQRDMLSH_LANE : SInst<"svqrdmlsh_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlsh_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; - -def SVQSHLU_M : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeOp1, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; -def SVQSHLU_X : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeAny, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; -def SVQSHLU_Z : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeZero, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; -def SVRSHR_M_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSHR_M_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeOp1, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSHR_X_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSHR_X_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeAny, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSHR_Z_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSHR_Z_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeZero, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSRA_S : SInst<"svrsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_srsra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVRSRA_U : SInst<"svrsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_ursra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVSLI : SInst<"svsli[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sli", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; -def SVSRA_S : SInst<"svsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_ssra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVSRA_U : SInst<"svsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_usra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; -def SVSRI : SInst<"svsri[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sri", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +defm SVQRSHL_S : SInstZPZxZ<"svqrshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqrshl", [IsStreamingCompatible]>; +defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl", [IsStreamingCompatible]>; +defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl", [IsStreamingCompatible]>; +defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl", [IsStreamingCompatible]>; +defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl", [IsStreamingCompatible]>; +defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl", [IsStreamingCompatible]>; +defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd", [IsStreamingCompatible]>; +defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd", [IsStreamingCompatible]>; + +def SVABA_S : SInst<"svaba[_{d}]", "dddd", "csil" , MergeNone, "aarch64_sve_saba", [IsStreamingCompatible]>; +def SVABA_U : SInst<"svaba[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uaba", [IsStreamingCompatible]>; +def SVQDMULH : SInst<"svqdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqdmulh", [IsStreamingCompatible]>; +def SVQRDMULH : SInst<"svqrdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqrdmulh", [IsStreamingCompatible]>; +def SVQRDMLAH : SInst<"svqrdmlah[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlah", [IsStreamingCompatible]>; +def SVQRDMLSH : SInst<"svqrdmlsh[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlsh", [IsStreamingCompatible]>; + +def SVABA_S_N : SInst<"svaba[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_saba", [IsStreamingCompatible]>; +def SVABA_U_N : SInst<"svaba[_n_{d}]", "ddda", "UcUsUiUl", MergeNone, "aarch64_sve_uaba", [IsStreamingCompatible]>; +def SVQDMULH_N : SInst<"svqdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqdmulh", [IsStreamingCompatible]>; +def SVQRDMULH_N : SInst<"svqrdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqrdmulh", [IsStreamingCompatible]>; +def SVQRDMLAH_N : SInst<"svqrdmlah[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlah", [IsStreamingCompatible]>; +def SVQRDMLSH_N : SInst<"svqrdmlsh[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlsh", [IsStreamingCompatible]>; + +def SVQDMULH_LANE : SInst<"svqdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqdmulh_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQRDMULH_LANE : SInst<"svqrdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqrdmulh_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQRDMLAH_LANE : SInst<"svqrdmlah_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlah_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQRDMLSH_LANE : SInst<"svqrdmlsh_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlsh_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; + +def SVQSHLU_M : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeOp1, "aarch64_sve_sqshlu", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVQSHLU_X : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeAny, "aarch64_sve_sqshlu", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVQSHLU_Z : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeZero, "aarch64_sve_sqshlu", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVRSHR_M_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_srshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_M_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeOp1, "aarch64_sve_urshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_X_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_srshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_X_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeAny, "aarch64_sve_urshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_Z_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_srshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_Z_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeZero, "aarch64_sve_urshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSRA_S : SInst<"svrsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_srsra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSRA_U : SInst<"svrsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_ursra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVSLI : SInst<"svsli[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sli", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVSRA_S : SInst<"svsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_ssra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVSRA_U : SInst<"svsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_usra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVSRI : SInst<"svsri[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sri", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1434,29 +1446,29 @@ multiclass SInstPairwise; -defm SVADDP_F : SInstPairwise<"svaddp", "hfd", "aarch64_sve_faddp">; -defm SVMAXNMP : SInstPairwise<"svmaxnmp", "hfd", "aarch64_sve_fmaxnmp">; -defm SVMAXP_F : SInstPairwise<"svmaxp", "hfd", "aarch64_sve_fmaxp">; -defm SVMAXP_S : SInstPairwise<"svmaxp", "csli", "aarch64_sve_smaxp">; -defm SVMAXP_U : SInstPairwise<"svmaxp", "UcUsUiUl", "aarch64_sve_umaxp">; -defm SVMINNMP : SInstPairwise<"svminnmp", "hfd", "aarch64_sve_fminnmp">; -defm SVMINP_F : SInstPairwise<"svminp", "hfd", "aarch64_sve_fminp">; -defm SVMINP_S : SInstPairwise<"svminp", "csli", "aarch64_sve_sminp">; -defm SVMINP_U : SInstPairwise<"svminp", "UcUsUiUl", "aarch64_sve_uminp">; +defm SVADDP : SInstPairwise<"svaddp", "csliUcUsUiUl", "aarch64_sve_addp", [IsStreamingCompatible]>; +defm SVADDP_F : SInstPairwise<"svaddp", "hfd", "aarch64_sve_faddp", [IsStreamingCompatible]>; +defm SVMAXNMP : SInstPairwise<"svmaxnmp", "hfd", "aarch64_sve_fmaxnmp", [IsStreamingCompatible]>; +defm SVMAXP_F : SInstPairwise<"svmaxp", "hfd", "aarch64_sve_fmaxp", [IsStreamingCompatible]>; +defm SVMAXP_S : SInstPairwise<"svmaxp", "csli", "aarch64_sve_smaxp", [IsStreamingCompatible]>; +defm SVMAXP_U : SInstPairwise<"svmaxp", "UcUsUiUl", "aarch64_sve_umaxp", [IsStreamingCompatible]>; +defm SVMINNMP : SInstPairwise<"svminnmp", "hfd", "aarch64_sve_fminnmp", [IsStreamingCompatible]>; +defm SVMINP_F : SInstPairwise<"svminp", "hfd", "aarch64_sve_fminp", [IsStreamingCompatible]>; +defm SVMINP_S : SInstPairwise<"svminp", "csli", "aarch64_sve_sminp", [IsStreamingCompatible]>; +defm SVMINP_U : SInstPairwise<"svminp", "UcUsUiUl", "aarch64_sve_uminp", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Widening pairwise arithmetic let TargetGuard = "sve2" in { -def SVADALP_S_M : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeOp1, "aarch64_sve_sadalp">; -def SVADALP_S_X : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeAny, "aarch64_sve_sadalp">; -def SVADALP_S_Z : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeZero, "aarch64_sve_sadalp">; +def SVADALP_S_M : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeOp1, "aarch64_sve_sadalp", [IsStreamingCompatible]>; +def SVADALP_S_X : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeAny, "aarch64_sve_sadalp", [IsStreamingCompatible]>; +def SVADALP_S_Z : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeZero, "aarch64_sve_sadalp", [IsStreamingCompatible]>; -def SVADALP_U_M : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeOp1, "aarch64_sve_uadalp">; -def SVADALP_U_X : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeAny, "aarch64_sve_uadalp">; -def SVADALP_U_Z : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeZero, "aarch64_sve_uadalp">; +def SVADALP_U_M : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeOp1, "aarch64_sve_uadalp", [IsStreamingCompatible]>; +def SVADALP_U_X : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeAny, "aarch64_sve_uadalp", [IsStreamingCompatible]>; +def SVADALP_U_Z : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeZero, "aarch64_sve_uadalp", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1464,56 +1476,56 @@ def SVADALP_U_Z : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeZero, "aarch64_s // let TargetGuard = "sve2" in { -def SVBCAX : SInst<"svbcax[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax">; -def SVBSL : SInst<"svbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl">; -def SVBSL1N : SInst<"svbsl1n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n">; -def SVBSL2N : SInst<"svbsl2n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n">; -def SVEOR3 : SInst<"sveor3[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3">; -def SVNBSL : SInst<"svnbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl">; - -def SVBCAX_N : SInst<"svbcax[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax">; -def SVBSL_N : SInst<"svbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl">; -def SVBSL1N_N : SInst<"svbsl1n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n">; -def SVBSL2N_N : SInst<"svbsl2n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n">; -def SVEOR3_N : SInst<"sveor3[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3">; -def SVNBSL_N : SInst<"svnbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl">; -def SVXAR_N : SInst<"svxar[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_xar", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVBCAX : SInst<"svbcax[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax", [IsStreamingCompatible]>; +def SVBSL : SInst<"svbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl", [IsStreamingCompatible]>; +def SVBSL1N : SInst<"svbsl1n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n", [IsStreamingCompatible]>; +def SVBSL2N : SInst<"svbsl2n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n", [IsStreamingCompatible]>; +def SVEOR3 : SInst<"sveor3[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3", [IsStreamingCompatible]>; +def SVNBSL : SInst<"svnbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl", [IsStreamingCompatible]>; + +def SVBCAX_N : SInst<"svbcax[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax", [IsStreamingCompatible]>; +def SVBSL_N : SInst<"svbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl", [IsStreamingCompatible]>; +def SVBSL1N_N : SInst<"svbsl1n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n", [IsStreamingCompatible]>; +def SVBSL2N_N : SInst<"svbsl2n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n", [IsStreamingCompatible]>; +def SVEOR3_N : SInst<"sveor3[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3", [IsStreamingCompatible]>; +def SVNBSL_N : SInst<"svnbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl", [IsStreamingCompatible]>; +def SVXAR_N : SInst<"svxar[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_xar", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Large integer arithmetic let TargetGuard = "sve2" in { -def SVADCLB : SInst<"svadclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclb">; -def SVADCLT : SInst<"svadclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclt">; -def SVSBCLB : SInst<"svsbclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclb">; -def SVSBCLT : SInst<"svsbclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclt">; +def SVADCLB : SInst<"svadclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclb", [IsStreamingCompatible]>; +def SVADCLT : SInst<"svadclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclt", [IsStreamingCompatible]>; +def SVSBCLB : SInst<"svsbclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclb", [IsStreamingCompatible]>; +def SVSBCLT : SInst<"svsbclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclt", [IsStreamingCompatible]>; -def SVADCLB_N : SInst<"svadclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclb">; -def SVADCLT_N : SInst<"svadclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclt">; -def SVSBCLB_N : SInst<"svsbclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclb">; -def SVSBCLT_N : SInst<"svsbclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclt">; +def SVADCLB_N : SInst<"svadclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclb", [IsStreamingCompatible]>; +def SVADCLT_N : SInst<"svadclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclt", [IsStreamingCompatible]>; +def SVSBCLB_N : SInst<"svsbclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclb", [IsStreamingCompatible]>; +def SVSBCLT_N : SInst<"svsbclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclt", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Multiplication by indexed elements let TargetGuard = "sve2" in { -def SVMLA_LANE_2 : SInst<"svmla_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLS_LANE_2 : SInst<"svmls_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMUL_LANE_2 : SInst<"svmul_lane[_{d}]", "dddi", "silUsUiUl", MergeNone, "aarch64_sve_mul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMLA_LANE_2 : SInst<"svmla_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLS_LANE_2 : SInst<"svmls_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mls_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMUL_LANE_2 : SInst<"svmul_lane[_{d}]", "dddi", "silUsUiUl", MergeNone, "aarch64_sve_mul_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Uniform complex integer arithmetic let TargetGuard = "sve2" in { -def SVCADD : SInst<"svcadd[_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cadd_x", [], [ImmCheck<2, ImmCheckComplexRot90_270>]>; -def SVSQCADD : SInst<"svqcadd[_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_sqcadd_x", [], [ImmCheck<2, ImmCheckComplexRot90_270>]>; -def SVCMLA : SInst<"svcmla[_{d}]", "ddddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmla_x", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>; -def SVCMLA_LANE_X : SInst<"svcmla_lane[_{d}]", "ddddii", "siUsUi", MergeNone, "aarch64_sve_cmla_lane_x", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, +def SVCADD : SInst<"svcadd[_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cadd_x", [IsStreamingCompatible], [ImmCheck<2, ImmCheckComplexRot90_270>]>; +def SVSQCADD : SInst<"svqcadd[_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_sqcadd_x", [IsStreamingCompatible], [ImmCheck<2, ImmCheckComplexRot90_270>]>; +def SVCMLA : SInst<"svcmla[_{d}]", "ddddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmla_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRotAll90>]>; +def SVCMLA_LANE_X : SInst<"svcmla_lane[_{d}]", "ddddii", "siUsUi", MergeNone, "aarch64_sve_cmla_lane_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, ImmCheck<4, ImmCheckComplexRotAll90>]>; -def SVSQRDCMLAH_X : SInst<"svqrdcmlah[_{d}]", "ddddi", "csil", MergeNone, "aarch64_sve_sqrdcmlah_x", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>; -def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si", MergeNone, "aarch64_sve_sqrdcmlah_lane_x", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, +def SVSQRDCMLAH_X : SInst<"svqrdcmlah[_{d}]", "ddddi", "csil", MergeNone, "aarch64_sve_sqrdcmlah_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRotAll90>]>; +def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si", MergeNone, "aarch64_sve_sqrdcmlah_lane_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, ImmCheck<4, ImmCheckComplexRotAll90>]>; } @@ -1521,18 +1533,18 @@ def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si", // SVE2 - Widening DSP operations multiclass SInstWideDSPAcc { - def : SInst; - def _N : SInst; + def : SInst; + def _N : SInst; } multiclass SInstWideDSPLong { - def : SInst; - def _N : SInst; + def : SInst; + def _N : SInst; } multiclass SInstWideDSPWide { - def : SInst; - def _N : SInst; + def : SInst; + def _N : SInst; } let TargetGuard = "sve2" in { @@ -1581,87 +1593,87 @@ defm SVSUBWB_U : SInstWideDSPWide<"svsubwb", "UsUiUl", "aarch64_sve_usubwb">; defm SVSUBWT_S : SInstWideDSPWide<"svsubwt", "sil", "aarch64_sve_ssubwt">; defm SVSUBWT_U : SInstWideDSPWide<"svsubwt", "UsUiUl", "aarch64_sve_usubwt">; -def SVSHLLB_S_N : SInst<"svshllb[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllb", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; -def SVSHLLB_U_N : SInst<"svshllb[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllb", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; -def SVSHLLT_S_N : SInst<"svshllt[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllt", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; -def SVSHLLT_U_N : SInst<"svshllt[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllt", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; - -def SVMOVLB_S_N : SInst<"svmovlb[_{d}]", "dh", "sil", MergeNone>; -def SVMOVLB_U_N : SInst<"svmovlb[_{d}]", "dh", "UsUiUl", MergeNone>; -def SVMOVLT_S_N : SInst<"svmovlt[_{d}]", "dh", "sil", MergeNone>; -def SVMOVLT_U_N : SInst<"svmovlt[_{d}]", "dh", "UsUiUl", MergeNone>; - -def SVMLALB_S_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLALB_U_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLALT_S_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLALT_U_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLSLB_S_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLSLB_U_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLSLT_S_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLSLT_U_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMULLB_S_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVMULLB_U_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVMULLT_S_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVMULLT_U_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVQDMLALB_LANE : SInst<"svqdmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVQDMLALT_LANE : SInst<"svqdmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVQDMLSLB_LANE : SInst<"svqdmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVQDMLSLT_LANE : SInst<"svqdmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVQDMULLB_LANE : SInst<"svqdmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVQDMULLT_LANE : SInst<"svqdmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVSHLLB_S_N : SInst<"svshllb[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; +def SVSHLLB_U_N : SInst<"svshllb[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; +def SVSHLLT_S_N : SInst<"svshllt[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllt", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; +def SVSHLLT_U_N : SInst<"svshllt[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllt", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; + +def SVMOVLB_S_N : SInst<"svmovlb[_{d}]", "dh", "sil", MergeNone, "", [IsStreamingCompatible]>; +def SVMOVLB_U_N : SInst<"svmovlb[_{d}]", "dh", "UsUiUl", MergeNone, "", [IsStreamingCompatible]>; +def SVMOVLT_S_N : SInst<"svmovlt[_{d}]", "dh", "sil", MergeNone, "", [IsStreamingCompatible]>; +def SVMOVLT_U_N : SInst<"svmovlt[_{d}]", "dh", "UsUiUl", MergeNone, "", [IsStreamingCompatible]>; + +def SVMLALB_S_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALB_U_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALT_S_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALT_U_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLB_S_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLB_U_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLT_S_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLT_U_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMULLB_S_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullb_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMULLB_U_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullb_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMULLT_S_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullt_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMULLT_U_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullt_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQDMLALB_LANE : SInst<"svqdmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMLALT_LANE : SInst<"svqdmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMLSLB_LANE : SInst<"svqdmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMLSLT_LANE : SInst<"svqdmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMULLB_LANE : SInst<"svqdmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullb_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQDMULLT_LANE : SInst<"svqdmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullt_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Narrowing DSP operations let TargetGuard = "sve2" in { -def SVADDHNB : SInst<"svaddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnb">; -def SVADDHNT : SInst<"svaddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnt">; -def SVRADDHNB : SInst<"svraddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb">; -def SVRADDHNT : SInst<"svraddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt">; -def SVRSUBHNB : SInst<"svrsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb">; -def SVRSUBHNT : SInst<"svrsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt">; -def SVSUBHNB : SInst<"svsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnb">; -def SVSUBHNT : SInst<"svsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnt">; - -def SVADDHNB_N : SInst<"svaddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_addhnb">; -def SVADDHNT_N : SInst<"svaddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_addhnt">; -def SVRADDHNB_N : SInst<"svraddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb">; -def SVRADDHNT_N : SInst<"svraddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt">; -def SVRSUBHNB_N : SInst<"svrsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb">; -def SVRSUBHNT_N : SInst<"svrsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt">; -def SVSUBHNB_N : SInst<"svsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_subhnb">; -def SVSUBHNT_N : SInst<"svsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_subhnt">; - -def SVSHRNB : SInst<"svshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVRSHRNB : SInst<"svrshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVQSHRUNB : SInst<"svqshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqshrunb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVQRSHRUNB : SInst<"svqrshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqrshrunb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVQSHRNB_S : SInst<"svqshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVQSHRNB_U : SInst<"svqshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVQRSHRNB_S : SInst<"svqrshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqrshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; -def SVQRSHRNB_U : SInst<"svqrshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; - -def SVSHRNT : SInst<"svshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVRSHRNT : SInst<"svrshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVQSHRUNT : SInst<"svqshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqshrunt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVQRSHRUNT : SInst<"svqrshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqrshrunt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVQSHRNT_S : SInst<"svqshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVQSHRNT_U : SInst<"svqshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVQRSHRNT_S : SInst<"svqrshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqrshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; -def SVQRSHRNT_U : SInst<"svqrshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVADDHNB : SInst<"svaddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnb", [IsStreamingCompatible]>; +def SVADDHNT : SInst<"svaddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnt", [IsStreamingCompatible]>; +def SVRADDHNB : SInst<"svraddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb", [IsStreamingCompatible]>; +def SVRADDHNT : SInst<"svraddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt", [IsStreamingCompatible]>; +def SVRSUBHNB : SInst<"svrsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb", [IsStreamingCompatible]>; +def SVRSUBHNT : SInst<"svrsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt", [IsStreamingCompatible]>; +def SVSUBHNB : SInst<"svsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnb", [IsStreamingCompatible]>; +def SVSUBHNT : SInst<"svsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnt", [IsStreamingCompatible]>; + +def SVADDHNB_N : SInst<"svaddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_addhnb", [IsStreamingCompatible]>; +def SVADDHNT_N : SInst<"svaddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_addhnt", [IsStreamingCompatible]>; +def SVRADDHNB_N : SInst<"svraddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb", [IsStreamingCompatible]>; +def SVRADDHNT_N : SInst<"svraddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt", [IsStreamingCompatible]>; +def SVRSUBHNB_N : SInst<"svrsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb", [IsStreamingCompatible]>; +def SVRSUBHNT_N : SInst<"svrsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt", [IsStreamingCompatible]>; +def SVSUBHNB_N : SInst<"svsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_subhnb", [IsStreamingCompatible]>; +def SVSUBHNT_N : SInst<"svsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_subhnt", [IsStreamingCompatible]>; + +def SVSHRNB : SInst<"svshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVRSHRNB : SInst<"svrshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQSHRUNB : SInst<"svqshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqshrunb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQRSHRUNB : SInst<"svqrshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqrshrunb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQSHRNB_S : SInst<"svqshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQSHRNB_U : SInst<"svqshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQRSHRNB_S : SInst<"svqrshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqrshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQRSHRNB_U : SInst<"svqrshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; + +def SVSHRNT : SInst<"svshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVRSHRNT : SInst<"svrshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQSHRUNT : SInst<"svqshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqshrunt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQRSHRUNT : SInst<"svqrshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqrshrunt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQSHRNT_S : SInst<"svqshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQSHRNT_U : SInst<"svqshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQRSHRNT_S : SInst<"svqrshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqrshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQRSHRNT_U : SInst<"svqrshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Unary narrowing operations let TargetGuard = "sve2" in { -def SVQXTNB_S : SInst<"svqxtnb[_{d}]", "hd", "sil", MergeNone, "aarch64_sve_sqxtnb">; -def SVQXTNB_U : SInst<"svqxtnb[_{d}]", "hd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnb">; -def SVQXTUNB_S : SInst<"svqxtunb[_{d}]", "ed", "sil", MergeNone, "aarch64_sve_sqxtunb">; +def SVQXTNB_S : SInst<"svqxtnb[_{d}]", "hd", "sil", MergeNone, "aarch64_sve_sqxtnb", [IsStreamingCompatible]>; +def SVQXTNB_U : SInst<"svqxtnb[_{d}]", "hd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnb", [IsStreamingCompatible]>; +def SVQXTUNB_S : SInst<"svqxtunb[_{d}]", "ed", "sil", MergeNone, "aarch64_sve_sqxtunb", [IsStreamingCompatible]>; -def SVQXTNT_S : SInst<"svqxtnt[_{d}]", "hhd", "sil", MergeNone, "aarch64_sve_sqxtnt">; -def SVQXTNT_U : SInst<"svqxtnt[_{d}]", "hhd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnt">; -def SVQXTUNT_S : SInst<"svqxtunt[_{d}]", "eed", "sil", MergeNone, "aarch64_sve_sqxtunt">; +def SVQXTNT_S : SInst<"svqxtnt[_{d}]", "hhd", "sil", MergeNone, "aarch64_sve_sqxtnt", [IsStreamingCompatible]>; +def SVQXTNT_U : SInst<"svqxtnt[_{d}]", "hhd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnt", [IsStreamingCompatible]>; +def SVQXTUNT_S : SInst<"svqxtunt[_{d}]", "eed", "sil", MergeNone, "aarch64_sve_sqxtunt", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1802,18 +1814,18 @@ def SVSTNT1W_SCATTER_INDEX_S : MInst<"svstnt1w_scatter[_{2}base]_index[_{d}]", " // SVE2 - Polynomial arithmetic let TargetGuard = "sve2" in { -def SVEORBT : SInst<"sveorbt[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt">; -def SVEORBT_N : SInst<"sveorbt[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt">; -def SVEORTB : SInst<"sveortb[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb">; -def SVEORTB_N : SInst<"sveortb[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb">; -def SVPMUL : SInst<"svpmul[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_pmul">; -def SVPMUL_N : SInst<"svpmul[_n_{d}]", "dda", "Uc", MergeNone, "aarch64_sve_pmul">; -def SVPMULLB : SInst<"svpmullb[_{d}]", "dhh", "UsUl", MergeNone>; -def SVPMULLB_N : SInst<"svpmullb[_n_{d}]", "dhR", "UsUl", MergeNone>; -def SVPMULLB_PAIR : SInst<"svpmullb_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullb_pair">; -def SVPMULLB_PAIR_N : SInst<"svpmullb_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullb_pair">; -def SVPMULLT : SInst<"svpmullt[_{d}]", "dhh", "UsUl", MergeNone>; -def SVPMULLT_N : SInst<"svpmullt[_n_{d}]", "dhR", "UsUl", MergeNone>; +def SVEORBT : SInst<"sveorbt[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt", [IsStreamingCompatible]>; +def SVEORBT_N : SInst<"sveorbt[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt", [IsStreamingCompatible]>; +def SVEORTB : SInst<"sveortb[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb", [IsStreamingCompatible]>; +def SVEORTB_N : SInst<"sveortb[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb", [IsStreamingCompatible]>; +def SVPMUL : SInst<"svpmul[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_pmul", [IsStreamingCompatible]>; +def SVPMUL_N : SInst<"svpmul[_n_{d}]", "dda", "Uc", MergeNone, "aarch64_sve_pmul", [IsStreamingCompatible]>; +def SVPMULLB : SInst<"svpmullb[_{d}]", "dhh", "UsUl", MergeNone, "", [IsStreamingCompatible]>; +def SVPMULLB_N : SInst<"svpmullb[_n_{d}]", "dhR", "UsUl", MergeNone, "", [IsStreamingCompatible]>; +def SVPMULLB_PAIR : SInst<"svpmullb_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullb_pair", [IsStreamingCompatible]>; +def SVPMULLB_PAIR_N : SInst<"svpmullb_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullb_pair", [IsStreamingCompatible]>; +def SVPMULLT : SInst<"svpmullt[_{d}]", "dhh", "UsUl", MergeNone, "", [IsStreamingCompatible]>; +def SVPMULLT_N : SInst<"svpmullt[_n_{d}]", "dhR", "UsUl", MergeNone, "", [IsStreamingCompatible]>; def SVPMULLT_PAIR : SInst<"svpmullt_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">; def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">; } @@ -1822,8 +1834,8 @@ def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", Mer // SVE2 - Complex integer dot product let TargetGuard = "sve2" in { -def SVCDOT : SInst<"svcdot[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_cdot", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>; -def SVCDOT_LANE : SInst<"svcdot_lane[_{d}]", "ddqqii", "il", MergeNone, "aarch64_sve_cdot_lane", [], [ImmCheck<4, ImmCheckComplexRotAll90>, +def SVCDOT : SInst<"svcdot[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_cdot", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRotAll90>]>; +def SVCDOT_LANE : SInst<"svcdot_lane[_{d}]", "ddqqii", "il", MergeNone, "aarch64_sve_cdot_lane", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>, ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; } @@ -1831,27 +1843,27 @@ def SVCDOT_LANE : SInst<"svcdot_lane[_{d}]", "ddqqii", "il", MergeNone, "aarch // SVE2 - Floating-point widening multiply-accumulate let TargetGuard = "sve2" in { -def SVMLALB_F : SInst<"svmlalb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalb">; -def SVMLALB_F_N : SInst<"svmlalb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalb">; -def SVMLALB_F_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLALT_F : SInst<"svmlalt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalt">; -def SVMLALT_F_N : SInst<"svmlalt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalt">; -def SVMLALT_F_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLSLB_F : SInst<"svmlslb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslb">; -def SVMLSLB_F_N : SInst<"svmlslb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslb">; -def SVMLSLB_F_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLSLT_F : SInst<"svmlslt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslt">; -def SVMLSLT_F_N : SInst<"svmlslt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslt">; -def SVMLSLT_F_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALB_F : SInst<"svmlalb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalb", [IsStreamingCompatible]>; +def SVMLALB_F_N : SInst<"svmlalb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalb", [IsStreamingCompatible]>; +def SVMLALB_F_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALT_F : SInst<"svmlalt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalt", [IsStreamingCompatible]>; +def SVMLALT_F_N : SInst<"svmlalt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalt", [IsStreamingCompatible]>; +def SVMLALT_F_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLB_F : SInst<"svmlslb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslb", [IsStreamingCompatible]>; +def SVMLSLB_F_N : SInst<"svmlslb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslb", [IsStreamingCompatible]>; +def SVMLSLB_F_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLT_F : SInst<"svmlslt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslt", [IsStreamingCompatible]>; +def SVMLSLT_F_N : SInst<"svmlslt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslt", [IsStreamingCompatible]>; +def SVMLSLT_F_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Floating-point integer binary logarithm let TargetGuard = "sve2" in { -def SVLOGB_M : SInst<"svlogb[_{d}]", "xxPd", "hfd", MergeOp1, "aarch64_sve_flogb">; -def SVLOGB_X : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeAnyExp, "aarch64_sve_flogb">; -def SVLOGB_Z : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeZeroExp, "aarch64_sve_flogb">; +def SVLOGB_M : SInst<"svlogb[_{d}]", "xxPd", "hfd", MergeOp1, "aarch64_sve_flogb", [IsStreamingCompatible]>; +def SVLOGB_X : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeAnyExp, "aarch64_sve_flogb", [IsStreamingCompatible]>; +def SVLOGB_Z : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeZeroExp, "aarch64_sve_flogb", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1873,32 +1885,32 @@ def SVNMATCH : SInst<"svnmatch[_{d}]", "PPdd", "csUcUs", MergeNone, "aarch64_sve //////////////////////////////////////////////////////////////////////////////// // SVE2 - Contiguous conflict detection let TargetGuard = "sve2" in { -def SVWHILERW_B : SInst<"svwhilerw[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilerw_b", [IsOverloadWhileRW]>; -def SVWHILERW_H : SInst<"svwhilerw[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>; -def SVWHILERW_S : SInst<"svwhilerw[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilerw_s", [IsOverloadWhileRW]>; -def SVWHILERW_D : SInst<"svwhilerw[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilerw_d", [IsOverloadWhileRW]>; +def SVWHILERW_B : SInst<"svwhilerw[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilerw_b", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILERW_H : SInst<"svwhilerw[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILERW_S : SInst<"svwhilerw[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilerw_s", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILERW_D : SInst<"svwhilerw[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilerw_d", [IsOverloadWhileRW, IsStreamingCompatible]>; -def SVWHILEWR_B : SInst<"svwhilewr[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilewr_b", [IsOverloadWhileRW]>; -def SVWHILEWR_H : SInst<"svwhilewr[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>; -def SVWHILEWR_S : SInst<"svwhilewr[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilewr_s", [IsOverloadWhileRW]>; -def SVWHILEWR_D : SInst<"svwhilewr[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilewr_d", [IsOverloadWhileRW]>; +def SVWHILEWR_B : SInst<"svwhilewr[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilewr_b", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILEWR_H : SInst<"svwhilewr[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILEWR_S : SInst<"svwhilewr[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilewr_s", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILEWR_D : SInst<"svwhilewr[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilewr_d", [IsOverloadWhileRW, IsStreamingCompatible]>; } let TargetGuard = "sve2,bf16" in { -def SVWHILERW_H_BF16 : SInst<"svwhilerw[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>; -def SVWHILEWR_H_BF16 : SInst<"svwhilewr[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>; +def SVWHILERW_H_BF16 : SInst<"svwhilerw[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW, IsStreamingCompatible]>; +def SVWHILEWR_H_BF16 : SInst<"svwhilewr[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW, IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// // SVE2 - Extended table lookup/permute let TargetGuard = "sve2" in { -def SVTBL2 : SInst<"svtbl2[_{d}]", "d2u", "csilUcUsUiUlhfd", MergeNone>; -def SVTBX : SInst<"svtbx[_{d}]", "dddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbx">; +def SVTBL2 : SInst<"svtbl2[_{d}]", "d2u", "csilUcUsUiUlhfd", MergeNone, "", [IsStreamingCompatible]>; +def SVTBX : SInst<"svtbx[_{d}]", "dddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbx", [IsStreamingCompatible]>; } let TargetGuard = "sve2,bf16" in { -def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u", "b", MergeNone>; -def SVTBX_BF16 : SInst<"svtbx[_{d}]", "dddu", "b", MergeNone, "aarch64_sve_tbx">; +def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u", "b", MergeNone, "", [IsStreamingCompatible]>; +def SVTBX_BF16 : SInst<"svtbx[_{d}]", "dddu", "b", MergeNone, "aarch64_sve_tbx", [IsStreamingCompatible]>; } //////////////////////////////////////////////////////////////////////////////// @@ -1946,117 +1958,104 @@ def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pm", "Pi", MergeNone, "", def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pm", "Pl", MergeNone, "", [IsStreamingCompatible], []>; } +// Standalone sve2.1 builtins +let TargetGuard = "sve2p1" in { +def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>; +def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>; +def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfdcsilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>; +def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>; +def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>; +def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>; +def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>; +def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>; + +def SVFMAXNMQV: SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>; +def SVFMINNMQV: SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>; +def SVFMAXQV: SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>; +def SVFMINQV: SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>; +} + let TargetGuard = "sve2p1|sme2" in { //FIXME: Replace IsStreamingCompatible with IsStreamingOrHasSVE2p1 when available def SVPEXT_SINGLE : SInst<"svpext_lane_{d}", "P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext", [IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>; def SVPEXT_X2 : SInst<"svpext_lane_{d}_x2", "2.P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>; + +def SVWHILEGE_COUNT : SInst<"svwhilege_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilege_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILEGT_COUNT : SInst<"svwhilegt_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilegt_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILELE_COUNT : SInst<"svwhilele_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilele_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILELT_COUNT : SInst<"svwhilelt_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilelt_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILELO_COUNT : SInst<"svwhilelt_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilelo_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILELS_COUNT : SInst<"svwhilele_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilels_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILEHI_COUNT : SInst<"svwhilegt_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilehi_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +def SVWHILEHS_COUNT : SInst<"svwhilege_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilehs_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; +} + +multiclass MultiVecLoad { + // FIXME: Replace IsStreamingCompatible with IsStreamingOrHasSVE2p1 when available (SME2 requires __arm_streaming) + def SV # NAME # B_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "cUc", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # H_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "sUshb", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # W_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "iUif", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # D_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "lUld", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # B_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "cUc", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # H_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "sUshb", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # W_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "iUif", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # D_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "lUld", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + + def SV # NAME # B_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "cUc", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # H_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "sUshb", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # W_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "iUif", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # D_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "lUld", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # B_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "cUc", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # H_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "sUshb", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # W_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "iUif", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # D_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "lUld", [IsStructLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; } -let TargetGuard = "sve2p1" in { -def SVFCLAMP : SInst<"svclamp[_{d}]", "dddd", "hfd", MergeNone, "aarch64_sve_fclamp", [], []>; - -def SVWHILEGE_COUNT : SInst<"svwhilege_{d}", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilege_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILEGT_COUNT : SInst<"svwhilegt_{d}", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilegt_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILELE_COUNT : SInst<"svwhilele_{d}", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilele_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILELT_COUNT : SInst<"svwhilelt_{d}", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilelt_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILELO_COUNT : SInst<"svwhilelo_{d}", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilelo_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILELS_COUNT : SInst<"svwhilels_{d}", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilels_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILEHI_COUNT : SInst<"svwhilehi_{d}", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilehi_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; -def SVWHILEHS_COUNT : SInst<"svwhilehs_{d}", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilehs_{d}", [IsOverloadNone], [ImmCheck<2, ImmCheck2_4_Mul2>]>; - -def SVLD1B_X2 : MInst<"svld1[_{2}]_x2", "2}c", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1H_X2 : MInst<"svld1[_{2}]_x2", "2}c", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1W_X2 : MInst<"svld1[_{2}]_x2", "2}c", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1D_X2 : MInst<"svld1[_{2}]_x2", "2}c", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1B_X4 : MInst<"svld1[_{2}]_x4", "4}c", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; -def SVLD1H_X4 : MInst<"svld1[_{2}]_x4", "4}c", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; -def SVLD1W_X4 : MInst<"svld1[_{2}]_x4", "4}c", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; -def SVLD1D_X4 : MInst<"svld1[_{2}]_x4", "4}c", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; - -def SVLDNT1B_X2 : MInst<"svldnt1[_{2}]_x2", "2}c", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1H_X2 : MInst<"svldnt1[_{2}]_x2", "2}c", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1W_X2 : MInst<"svldnt1[_{2}]_x2", "2}c", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1D_X2 : MInst<"svldnt1[_{2}]_x2", "2}c", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1B_X4 : MInst<"svldnt1[_{2}]_x4", "4}c", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; -def SVLDNT1H_X4 : MInst<"svldnt1[_{2}]_x4", "4}c", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; -def SVLDNT1W_X4 : MInst<"svldnt1[_{2}]_x4", "4}c", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; -def SVLDNT1D_X4 : MInst<"svldnt1[_{2}]_x4", "4}c", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; - -def SVLD1B_VNUM_X2 : MInst<"svld1_vnum[_{2}]_x2", "2}cl", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1H_VNUM_X2 : MInst<"svld1_vnum[_{2}]_x2", "2}cl", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1W_VNUM_X2 : MInst<"svld1_vnum[_{2}]_x2", "2}cl", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1D_VNUM_X2 : MInst<"svld1_vnum[_{2}]_x2", "2}cl", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x2">; -def SVLD1B_VNUM_X4 : MInst<"svld1_vnum[_{2}]_x4", "4}cl", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; -def SVLD1H_VNUM_X4 : MInst<"svld1_vnum[_{2}]_x4", "4}cl", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; -def SVLD1W_VNUM_X4 : MInst<"svld1_vnum[_{2}]_x4", "4}cl", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; -def SVLD1D_VNUM_X4 : MInst<"svld1_vnum[_{2}]_x4", "4}cl", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ld1_pn_x4">; - -def SVLDNT1B_VNUM_X2 : MInst<"svldnt1_vnum[_{2}]_x2", "2}cl", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1H_VNUM_X2 : MInst<"svldnt1_vnum[_{2}]_x2", "2}cl", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1W_VNUM_X2 : MInst<"svldnt1_vnum[_{2}]_x2", "2}cl", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1D_VNUM_X2 : MInst<"svldnt1_vnum[_{2}]_x2", "2}cl", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x2">; -def SVLDNT1B_VNUM_X4 : MInst<"svldnt1_vnum[_{2}]_x4", "4}cl", "cUc", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; -def SVLDNT1H_VNUM_X4 : MInst<"svldnt1_vnum[_{2}]_x4", "4}cl", "sUshb", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; -def SVLDNT1W_VNUM_X4 : MInst<"svldnt1_vnum[_{2}]_x4", "4}cl", "iUif", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; -def SVLDNT1D_VNUM_X4 : MInst<"svldnt1_vnum[_{2}]_x4", "4}cl", "lUld", [IsStructLoad], MemEltTyDefault, "aarch64_sve_ldnt1_pn_x4">; - -def SVST1B_X2 : MInst<"svst1[_{2}_x2]", "v}p2", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1H_X2 : MInst<"svst1[_{2}_x2]", "v}p2", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1W_X2 : MInst<"svst1[_{2}_x2]", "v}p2", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1D_X2 : MInst<"svst1[_{2}_x2]", "v}p2", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1B_X4 : MInst<"svst1[_{2}_x4]", "v}p4", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; -def SVST1H_X4 : MInst<"svst1[_{2}_x4]", "v}p4", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; -def SVST1W_X4 : MInst<"svst1[_{2}_x4]", "v}p4", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; -def SVST1D_X4 : MInst<"svst1[_{2}_x4]", "v}p4", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; - -def SVST1B_VNUM_X2 : MInst<"svst1_vnum[_{2}_x2]", "v}pl2", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1H_VNUM_X2 : MInst<"svst1_vnum[_{2}_x2]", "v}pl2", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1W_VNUM_X2 : MInst<"svst1_vnum[_{2}_x2]", "v}pl2", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1D_VNUM_X2 : MInst<"svst1_vnum[_{2}_x2]", "v}pl2", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x2">; -def SVST1B_VNUM_X4 : MInst<"svst1_vnum[_{2}_x4]", "v}pl4", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; -def SVST1H_VNUM_X4 : MInst<"svst1_vnum[_{2}_x4]", "v}pl4", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; -def SVST1W_VNUM_X4 : MInst<"svst1_vnum[_{2}_x4]", "v}pl4", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; -def SVST1D_VNUM_X4 : MInst<"svst1_vnum[_{2}_x4]", "v}pl4", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_st1_pn_x4">; - -def SVSTNT1B_X2 : MInst<"svstnt1[_{2}_x2]", "v}p2", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1H_X2 : MInst<"svstnt1[_{2}_x2]", "v}p2", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1W_X2 : MInst<"svstnt1[_{2}_x2]", "v}p2", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1D_X2 : MInst<"svstnt1[_{2}_x2]", "v}p2", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1B_X4 : MInst<"svstnt1[_{2}_x4]", "v}p4", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; -def SVSTNT1H_X4 : MInst<"svstnt1[_{2}_x4]", "v}p4", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; -def SVSTNT1W_X4 : MInst<"svstnt1[_{2}_x4]", "v}p4", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; -def SVSTNT1D_X4 : MInst<"svstnt1[_{2}_x4]", "v}p4", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; - -def SVSTNT1B_VNUM_X2 : MInst<"svstnt1_vnum[_{2}_x2]", "v}pl2", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1H_VNUM_X2 : MInst<"svstnt1_vnum[_{2}_x2]", "v}pl2", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1W_VNUM_X2 : MInst<"svstnt1_vnum[_{2}_x2]", "v}pl2", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1D_VNUM_X2 : MInst<"svstnt1_vnum[_{2}_x2]", "v}pl2", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x2">; -def SVSTNT1B_VNUM_X4 : MInst<"svstnt1_vnum[_{2}_x4]", "v}pl4", "cUc", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; -def SVSTNT1H_VNUM_X4 : MInst<"svstnt1_vnum[_{2}_x4]", "v}pl4", "sUshb", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; -def SVSTNT1W_VNUM_X4 : MInst<"svstnt1_vnum[_{2}_x4]", "v}pl4", "iUif", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; -def SVSTNT1D_VNUM_X4 : MInst<"svstnt1_vnum[_{2}_x4]", "v}pl4", "lUld", [IsStructStore], MemEltTyDefault, "aarch64_sve_stnt1_pn_x4">; +let TargetGuard = "sve2p1|sme2" in { + defm LD1 : MultiVecLoad<"ld1">; + defm LDNT1 : MultiVecLoad<"ldnt1">; +} + +multiclass MultiVecStore { + // FIXME: Replace IsStreamingCompatible with IsStreamingOrHasSVE2p1 when available (SME2 requires __arm_streaming) + def SV # NAME # B_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "cUc", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # H_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "sUshb", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # W_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "iUif", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # D_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "lUld", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # B_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "cUc", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # H_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "sUshb", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # W_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "iUif", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # D_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "lUld", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + + def SV # NAME # B_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "cUc", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # H_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "sUshb", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # W_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "iUif", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # D_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "lUld", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">; + def SV # NAME # B_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "cUc", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # H_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "sUshb", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # W_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "iUif", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; + def SV # NAME # D_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "lUld", [IsStructStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">; +} + +let TargetGuard = "sve2p1|sme2" in { + defm ST1 : MultiVecStore<"st1">; + defm STNT1 : MultiVecStore<"stnt1">; +} +let TargetGuard = "sve2p1" in { def SVDOT_X2_S : SInst<"svdot[_{d}_{2}_{3}]", "ddhh", "i", MergeNone, "aarch64_sve_sdot_x2", [], []>; def SVDOT_X2_U : SInst<"svdot[_{d}_{2}_{3}]", "ddhh", "Ui", MergeNone, "aarch64_sve_udot_x2", [], []>; def SVDOT_X2_F : SInst<"svdot[_{d}_{2}_{3}]", "ddhh", "f", MergeNone, "aarch64_sve_fdot_x2", [], []>; def SVDOT_LANE_X2_S : SInst<"svdot_lane[_{d}_{2}_{3}]", "ddhhi", "i", MergeNone, "aarch64_sve_sdot_lane_x2", [], [ImmCheck<3, ImmCheck0_3>]>; def SVDOT_LANE_X2_U : SInst<"svdot_lane[_{d}_{2}_{3}]", "ddhhi", "Ui", MergeNone, "aarch64_sve_udot_lane_x2", [], [ImmCheck<3, ImmCheck0_3>]>; def SVDOT_LANE_X2_F : SInst<"svdot_lane[_{d}_{2}_{3}]", "ddhhi", "f", MergeNone, "aarch64_sve_fdot_lane_x2", [], [ImmCheck<3, ImmCheck0_3>]>; - -def SVBFMLSLB : SInst<"svbfmlslb[_{d}]", "dd$$", "f", MergeNone, "aarch64_sve_bfmlslb", [IsOverloadNone], []>; -def SVBFMLSLT : SInst<"svbfmlslt[_{d}]", "dd$$", "f", MergeNone, "aarch64_sve_bfmlslt", [IsOverloadNone], []>; - -def SVBFMLSLB_LANE : SInst<"svbfmlslb_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslb_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; -def SVBFMLSLT_LANE : SInst<"svbfmlslt_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslt_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; } -let TargetGuard = "sve2p1" in { +let TargetGuard = "sve2p1|sme" in { def SVSCLAMP : SInst<"svclamp[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sclamp", [], []>; def SVUCLAMP : SInst<"svclamp[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp", [], []>; -def SVCNTP_COUNT : SInst<"svcntp_{d}", "n}i", "QcQsQiQl", MergeNone, "aarch64_sve_cntp_{d}", [IsOverloadNone], [ImmCheck<1, ImmCheck2_4_Mul2>]>; - -defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUl", "aarch64_sve_revd">; +defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUlbhfd", "aarch64_sve_revd">; } let TargetGuard = "sve2p1|sme2" in { @@ -2064,23 +2063,26 @@ let TargetGuard = "sve2p1|sme2" in { def SVPTRUE_COUNT : SInst<"svptrue_{d}", "}v", "QcQsQiQl", MergeNone, "aarch64_sve_ptrue_{d}", [IsOverloadNone, IsStreamingCompatible], []>; def SVPFALSE_COUNT_ALIAS : SInst<"svpfalse_c", "}v", "", MergeNone, "", [IsOverloadNone, IsStreamingCompatible]>; + + def SVFCLAMP : SInst<"svclamp[_{d}]", "dddd", "hfd", MergeNone, "aarch64_sve_fclamp", [IsStreamingCompatible], []>; + def SVCNTP_COUNT : SInst<"svcntp_{d}", "n}i", "QcQsQiQl", MergeNone, "aarch64_sve_cntp_{d}", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<1, ImmCheck2_4_Mul2>]>; } -let TargetGuard = "sve2p1,b16b16" in { -defm SVMUL_BF : SInstZPZZ<"svmul", "b", "aarch64_sve_fmul", "aarch64_sve_fmul_u">; -defm SVADD_BF : SInstZPZZ<"svadd", "b", "aarch64_sve_fadd", "aarch64_sve_fadd_u">; -defm SVSUB_BF : SInstZPZZ<"svsub", "b", "aarch64_sve_fsub", "aarch64_sve_fsub_u">; -defm SVMAXNM_BF : SInstZPZZ<"svmaxnm","b", "aarch64_sve_fmaxnm", "aarch64_sve_fmaxnm_u">; -defm SVMINNM_BF : SInstZPZZ<"svminnm","b", "aarch64_sve_fminnm", "aarch64_sve_fminnm_u">; -defm SVMAX_BF : SInstZPZZ<"svmax", "b", "aarch64_sve_fmax", "aarch64_sve_fmax_u">; -defm SVMIN_BF : SInstZPZZ<"svmin", "b", "aarch64_sve_fmin", "aarch64_sve_fmin_u">; -defm SVMLA_BF : SInstZPZZZ<"svmla", "b", "aarch64_sve_fmla", "aarch64_sve_fmla_u", []>; -defm SVMLS_BF : SInstZPZZZ<"svmls", "b", "aarch64_sve_fmls", "aarch64_sve_fmls_u", []>; -def SVMLA_LANE_BF : SInst<"svmla_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMLS_LANE_BF : SInst<"svmls_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; -def SVMUL_LANE_BF : SInst<"svmul_lane[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_fmul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; -def SVFCLAMP_BF : SInst<"svclamp[_{d}]", "dddd", "b", MergeNone, "aarch64_sve_fclamp", [], []>; -} //sve2p1,b16b16 +let TargetGuard = "(sve2|sme2),b16b16" in { +defm SVMUL_BF : SInstZPZZ<"svmul", "b", "aarch64_sve_fmul", "aarch64_sve_fmul_u", [IsStreamingCompatible]>; +defm SVADD_BF : SInstZPZZ<"svadd", "b", "aarch64_sve_fadd", "aarch64_sve_fadd_u", [IsStreamingCompatible]>; +defm SVSUB_BF : SInstZPZZ<"svsub", "b", "aarch64_sve_fsub", "aarch64_sve_fsub_u", [IsStreamingCompatible]>; +defm SVMAXNM_BF : SInstZPZZ<"svmaxnm","b", "aarch64_sve_fmaxnm", "aarch64_sve_fmaxnm_u", [IsStreamingCompatible]>; +defm SVMINNM_BF : SInstZPZZ<"svminnm","b", "aarch64_sve_fminnm", "aarch64_sve_fminnm_u", [IsStreamingCompatible]>; +defm SVMAX_BF : SInstZPZZ<"svmax", "b", "aarch64_sve_fmax", "aarch64_sve_fmax_u", [IsStreamingCompatible]>; +defm SVMIN_BF : SInstZPZZ<"svmin", "b", "aarch64_sve_fmin", "aarch64_sve_fmin_u", [IsStreamingCompatible]>; +defm SVMLA_BF : SInstZPZZZ<"svmla", "b", "aarch64_sve_fmla", "aarch64_sve_fmla_u", [IsStreamingCompatible]>; +defm SVMLS_BF : SInstZPZZZ<"svmls", "b", "aarch64_sve_fmls", "aarch64_sve_fmls_u", [IsStreamingCompatible]>; +def SVMLA_LANE_BF : SInst<"svmla_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLS_LANE_BF : SInst<"svmls_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmls_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMUL_LANE_BF : SInst<"svmul_lane[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_fmul_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVFCLAMP_BF : SInst<"svclamp[_{d}]", "dddd", "b", MergeNone, "aarch64_sve_fclamp", [IsStreamingCompatible], []>; +} // SME2 @@ -2121,6 +2123,21 @@ let TargetGuard = "sme2" in { defm SVMAXNM : SInstMinMaxByVector<"max">; } +let TargetGuard = "sme2" in { + // FRINTA / FRINTM / FRINTN / FRINTP + def SVRINTA_X2 : SInst<"svrinta[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frinta_x2", [IsStreaming], []>; + def SVRINTA_X4 : SInst<"svrinta[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frinta_x4", [IsStreaming], []>; + + def SVRINTM_X2 : SInst<"svrintm[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frintm_x2", [IsStreaming], []>; + def SVRINTM_X4 : SInst<"svrintm[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frintm_x4", [IsStreaming], []>; + + def SVRINTN_X2 : SInst<"svrintn[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frintn_x2", [IsStreaming], []>; + def SVRINTN_X4 : SInst<"svrintn[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frintn_x4", [IsStreaming], []>; + + def SVRINTP_X2 : SInst<"svrintp[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frintp_x2", [IsStreaming], []>; + def SVRINTP_X4 : SInst<"svrintp[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frintp_x4", [IsStreaming], []>; +} + let TargetGuard = "sme2" in { def SVSCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "csil", MergeNone, "aarch64_sve_sclamp_single_x2", [IsStreaming], []>; def SVUCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp_single_x2", [IsStreaming], []>; @@ -2168,6 +2185,21 @@ let TargetGuard = "sme2" in { def REINTERPRET_SVBOOL_TO_SVCOUNT : Inst<"svreinterpret[_c]", "}P", "Pc", MergeNone, "", [IsStreamingCompatible], []>; def REINTERPRET_SVCOUNT_TO_SVBOOL : Inst<"svreinterpret[_b]", "P}", "Pc", MergeNone, "", [IsStreamingCompatible], []>; + + // SQDMULH + def SVSQDMULH_SINGLE_X2 : SInst<"svqdmulh[_single_{d}_x2]", "22d", "csil", MergeNone, "aarch64_sve_sqdmulh_single_vgx2", [IsStreaming], []>; + def SVSQDMULH_SINGLE_X4 : SInst<"svqdmulh[_single_{d}_x4]", "44d", "csil", MergeNone, "aarch64_sve_sqdmulh_single_vgx4", [IsStreaming], []>; + def SVSQDMULH_X2 : SInst<"svqdmulh[_{d}_x2]", "222", "csil", MergeNone, "aarch64_sve_sqdmulh_vgx2", [IsStreaming], []>; + def SVSQDMULH_X4 : SInst<"svqdmulh[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_sqdmulh_vgx4", [IsStreaming], []>; +} + +let TargetGuard = "sve2p1|sme2" in { + // SQRSHRN / UQRSHRN + def SVQRSHRN_X2 : SInst<"svqrshrn[_n]_{0}[_{d}_x2]", "h2i", "i", MergeNone, "aarch64_sve_sqrshrn_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>; + def SVUQRSHRN_X2 : SInst<"svqrshrn[_n]_{0}[_{d}_x2]", "e2i", "Ui", MergeNone, "aarch64_sve_uqrshrn_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>; + + // SQRSHRUN + def SVSQRSHRUN_X2 : SInst<"svqrshrun[_n]_{0}[_{d}_x2]", "e2i", "i", MergeNone, "aarch64_sve_sqrshrun_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>; } let TargetGuard = "sve2p1" in { @@ -2249,11 +2281,13 @@ let TargetGuard = "sme2" in { // // Multi-vector saturating extract narrow and interleave // -let TargetGuard = "sme2" in { +let TargetGuard = "sme2|sve2p1" in { def SVQCVTN_S16_S32_X2 : SInst<"svqcvtn_s16[_{d}_x2]", "h2.d", "i", MergeNone, "aarch64_sve_sqcvtn_x2", [IsStreamingCompatible], []>; def SVQCVTN_U16_U32_X2 : SInst<"svqcvtn_u16[_{d}_x2]", "e2.d", "Ui", MergeNone, "aarch64_sve_uqcvtn_x2", [IsStreamingCompatible], []>; def SVQCVTN_U16_S32_X2 : SInst<"svqcvtn_u16[_{d}_x2]", "e2.d", "i", MergeNone, "aarch64_sve_sqcvtun_x2", [IsStreamingCompatible], []>; +} +let TargetGuard = "sme2" in { def SVQCVTN_S8_S32_X4 : SInst<"svqcvtn_s8[_{d}_x4]", "q4.d", "i", MergeNone, "aarch64_sve_sqcvtn_x4", [IsStreaming], []>; def SVQCVTN_U8_U32_X4 : SInst<"svqcvtn_u8[_{d}_x4]", "b4.d", "Ui", MergeNone, "aarch64_sve_uqcvtn_x4", [IsStreaming], []>; def SVQCVTN_U8_S32_X4 : SInst<"svqcvtn_u8[_{d}_x4]", "b4.d", "i", MergeNone, "aarch64_sve_sqcvtun_x4", [IsStreaming], []>; @@ -2263,6 +2297,22 @@ let TargetGuard = "sme2" in { def SVQCVTN_U16_S64_X4 : SInst<"svqcvtn_u16[_{d}_x4]", "b4.d", "l", MergeNone, "aarch64_sve_sqcvtun_x4", [IsStreaming], []>; } +// +// Multi-vector zip/unzip +// + +let TargetGuard = "sme2" in { + def SVZIP_X2 : SInst<"svzip[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zip_x2", [IsStreaming], []>; + def SVZIPQ_X2 : SInst<"svzipq[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq_x2", [IsStreaming], []>; + def SVZIP_X4 : SInst<"svzip[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zip_x4", [IsStreaming], []>; + def SVZIPQ_X4 : SInst<"svzipq[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq_x4", [IsStreaming], []>; + + def SVUZP_X2 : SInst<"svuzp[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzp_x2", [IsStreaming], []>; + def SVUZPQ_X2 : SInst<"svuzpq[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq_x2", [IsStreaming], []>; + def SVUZP_X4 : SInst<"svuzp[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzp_x4", [IsStreaming], []>; + def SVUZPQ_X4 : SInst<"svuzpq[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq_x4", [IsStreaming], []>; +} + // // Multi-vector unpack // @@ -2273,3 +2323,13 @@ let TargetGuard = "sme2" in { def SVSUNPK_X4 : SInst<"svunpk_{d}[_{3}_x4]", "42.h", "sil", MergeNone, "aarch64_sve_sunpk_x4", [IsStreaming], []>; def SVUUNPK_X4 : SInst<"svunpk_{d}[_{3}_x4]", "42.h", "UsUiUl", MergeNone, "aarch64_sve_uunpk_x4", [IsStreaming], []>; } + +let TargetGuard = "sve2p1|sme2" in { +// == BFloat16 multiply-subtract == +// FIXME: Make all of these IsStreamingOrSVE2p1 once that is added + def SVBFMLSLB : SInst<"svbfmlslb[_{d}]", "dd$$", "f", MergeNone, "aarch64_sve_bfmlslb", [IsOverloadNone, IsStreamingCompatible], []>; + def SVBFMLSLT : SInst<"svbfmlslt[_{d}]", "dd$$", "f", MergeNone, "aarch64_sve_bfmlslt", [IsOverloadNone, IsStreamingCompatible], []>; + + def SVBFMLSLB_LANE : SInst<"svbfmlslb_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslb_lane", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_7>]>; + def SVBFMLSLT_LANE : SInst<"svbfmlslt_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslt_lane", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_7>]>; +} diff --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td index 040ce95a57de3dc43385269897de2e0816c5da40..0dba8493bad2d6a48e70cb3382c8161dc47debdb 100644 --- a/clang/include/clang/Basic/arm_sve_sme_incl.td +++ b/clang/include/clang/Basic/arm_sve_sme_incl.td @@ -129,6 +129,7 @@ // Z: const pointer to uint64_t // Prototype modifiers added for SVE2p1 +// {: 128b vector // }: svcount_t class MergeType { @@ -225,6 +226,7 @@ def IsSharedZA : FlagType<0x8000000000>; def IsPreservesZA : FlagType<0x10000000000>; def IsReadZA : FlagType<0x20000000000>; def IsWriteZA : FlagType<0x40000000000>; +def IsReductionQV : FlagType<0x80000000000>; // These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h class ImmCheckType { diff --git a/clang/include/clang/Basic/riscv_sifive_vector.td b/clang/include/clang/Basic/riscv_sifive_vector.td index bb54e26641861480e41c517853f321fb65a0712b..0d471f6c554c2296b03407ec1632b921ddb7ecc8 100644 --- a/clang/include/clang/Basic/riscv_sifive_vector.td +++ b/clang/include/clang/Basic/riscv_sifive_vector.td @@ -109,10 +109,10 @@ multiclass RVVVFWMACCBuiltinSet> suffixes_prototypes> { Name = NAME, HasMasked = false, Log2LMUL = [-2, -1, 0, 1, 2] in - defm NAME : RVVOutOp1Op2BuiltinSet; + defm NAME : RVVOutOp1Op2BuiltinSet; } -multiclass RVVVQMACCBuiltinSet> suffixes_prototypes> { +multiclass RVVVQMACCDODBuiltinSet> suffixes_prototypes> { let OverloadedName = NAME, Name = NAME, HasMasked = false, @@ -120,6 +120,14 @@ multiclass RVVVQMACCBuiltinSet> suffixes_prototypes> { defm NAME : RVVOutOp1Op2BuiltinSet; } +multiclass RVVVQMACCQOQBuiltinSet> suffixes_prototypes> { + let OverloadedName = NAME, + Name = NAME, + HasMasked = false, + Log2LMUL = [-1, 0, 1, 2] in + defm NAME : RVVOutOp1Op2BuiltinSet; +} + multiclass RVVVFNRCLIPBuiltinSet { let Log2LMUL = [-3, -2, -1, 0, 1, 2], Name = NAME, @@ -130,18 +138,18 @@ multiclass RVVVFNRCLIPBuiltinSet; - defm sf_vqmacc_2x8x2 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)v"]]>; - defm sf_vqmaccus_2x8x2 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)v"]]>; - defm sf_vqmaccsu_2x8x2 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; + defm sf_vqmaccu_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>; + defm sf_vqmacc_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)v"]]>; + defm sf_vqmaccus_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)v"]]>; + defm sf_vqmaccsu_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; } let UnMaskedPolicyScheme = HasPolicyOperand in let RequiredFeatures = ["Xsfvqmaccqoq"] in { - defm sf_vqmaccu_4x8x4 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>; - defm sf_vqmacc_4x8x4 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)v"]]>; - defm sf_vqmaccus_4x8x4 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)v"]]>; - defm sf_vqmaccsu_4x8x4 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; + defm sf_vqmaccu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>; + defm sf_vqmacc_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)v"]]>; + defm sf_vqmaccus_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)SUv(FixedSEW:8)v"]]>; + defm sf_vqmaccsu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; } let UnMaskedPolicyScheme = HasPolicyOperand in diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index 682f1d5c8af68c08e376b6226582d687930bdd0b..e7d78b03511fe9a8440f700b0abcbffdbb7b160f 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -2441,11 +2441,9 @@ let HasMasked = false, HasVL = false, IRName = "" in { return Builder.CreateInsertVector(ResultType, Ops[0], Ops[2], Ops[1]); } }] in { - let Log2LMUL = [0, 1, 2] in { - foreach dst_lmul = ["(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in { - def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilxfd">; - def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "Uv" # dst_lmul #"UvKzUv", "csil">; - } + foreach dst_lmul = ["(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in { + def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilxfd">; + def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "Uv" # dst_lmul #"UvKzUv", "csil">; } foreach nf = NFList in { defvar T = "(Tuple:" # nf # ")"; @@ -2540,7 +2538,7 @@ multiclass RVVSignedWidenBinBuiltinSetVwsll let UnMaskedPolicyScheme = HasPassthruOperand in { // zvkb - let RequiredFeatures = ["Zvkb"] in { + let RequiredFeatures = ["Zvkb", "Experimental"] in { defm vandn : RVVUnsignedBinBuiltinSet; defm vbrev8 : RVVOutBuiltinSetZvbb; defm vrev8 : RVVOutBuiltinSetZvbb; @@ -2549,7 +2547,7 @@ let UnMaskedPolicyScheme = HasPassthruOperand in { } // zvbb - let RequiredFeatures = ["Zvbb"] in { + let RequiredFeatures = ["Zvbb", "Experimental"] in { defm vbrev : RVVOutBuiltinSetZvbb; defm vclz : RVVOutBuiltinSetZvbb; defm vctz : RVVOutBuiltinSetZvbb; @@ -2559,7 +2557,7 @@ let UnMaskedPolicyScheme = HasPassthruOperand in { } // zvbc - let RequiredFeatures = ["Zvbc"] in { + let RequiredFeatures = ["Zvbc", "Experimental"] in { defm vclmul : RVVInt64BinBuiltinSet; defm vclmulh : RVVInt64BinBuiltinSet; } @@ -2567,13 +2565,13 @@ let UnMaskedPolicyScheme = HasPassthruOperand in { let UnMaskedPolicyScheme = HasPolicyOperand, HasMasked = false in { // zvkg - let RequiredFeatures = ["Zvkg"] in { + let RequiredFeatures = ["Zvkg", "Experimental"] in { defm vghsh : RVVOutOp2BuiltinSetVVZvk; defm vgmul : RVVOutBuiltinSetZvk; } // zvkned - let RequiredFeatures = ["Zvkned"] in { + let RequiredFeatures = ["Zvkned", "Experimental"] in { defm vaesdf : RVVOutBuiltinSetZvk; defm vaesdm : RVVOutBuiltinSetZvk; defm vaesef : RVVOutBuiltinSetZvk; @@ -2585,28 +2583,28 @@ let UnMaskedPolicyScheme = HasPolicyOperand, HasMasked = false in { } // zvknha - let RequiredFeatures = ["Zvknha"] in { + let RequiredFeatures = ["Zvknha", "Experimental"] in { defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"i">; defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"i">; defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"i">; } // zvknhb - let RequiredFeatures = ["Zvknhb"] in { + let RequiredFeatures = ["Zvknhb", "Experimental"] in { defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"il">; defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"il">; defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"il">; } // zvksed - let RequiredFeatures = ["Zvksed"] in { + let RequiredFeatures = ["Zvksed", "Experimental"] in { let UnMaskedPolicyScheme = HasPassthruOperand in defm vsm4k : RVVOutOp1BuiltinSet<"vsm4k", "i", [["vi", "Uv", "UvUvKz"]]>; defm vsm4r : RVVOutBuiltinSetZvk; } // zvksh - let RequiredFeatures = ["Zvksh"] in { + let RequiredFeatures = ["Zvksh", "Experimental"] in { defm vsm3c : RVVOutOp2BuiltinSetVIZvk; let UnMaskedPolicyScheme = HasPassthruOperand in defm vsm3me : RVVOutOp1BuiltinSet<"vsm3me", "i", [["vv", "Uv", "UvUvUv"]]>; diff --git a/clang/include/clang/Basic/riscv_vector_common.td b/clang/include/clang/Basic/riscv_vector_common.td index 4036ce8e6903f426c81adbfa840a2a90c9123dcc..040db6f0cdbfb0b28ec0a6ed8cf29b72da213ab4 100644 --- a/clang/include/clang/Basic/riscv_vector_common.td +++ b/clang/include/clang/Basic/riscv_vector_common.td @@ -41,7 +41,7 @@ // x: float16_t (half) // f: float32_t (float) // d: float64_t (double) -// b: bfloat16_t (bfloat16) +// y: bfloat16_t (bfloat16) // // This way, given an LMUL, a record with a TypeRange "sil" will cause the // definition of 3 builtins. Each type "t" in the TypeRange (in this example diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake index a54a26cd32ffe40ff655db4eb1c69bbf61c7f2da..4015ac8040861c2cb92d0c79a4334d5d3324dcb3 100644 --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -57,6 +57,12 @@ /* Define if we have sys/resource.h (rlimits) */ #cmakedefine CLANG_HAVE_RLIMITS ${CLANG_HAVE_RLIMITS} +/* Define if we have dlfcn.h */ +#cmakedefine CLANG_HAVE_DLFCN_H ${CLANG_HAVE_DLFCN_H} + +/* Define if dladdr() is available on this platform. */ +#cmakedefine CLANG_HAVE_DLADDR ${CLANG_HAVE_DLADDR} + /* Linker version detected at compile time. */ #cmakedefine HOST_LINK_VERSION "${HOST_LINK_VERSION}" diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 25c76cf2ad2c84ad15c2ac6a39390043477afd91..2b93ddf033499cc485d14d716c7f2a2d9f29dd2f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2896,9 +2896,11 @@ defm asm_blocks : BoolFOption<"asm-blocks", LangOpts<"AsmBlocks">, Default, PosFlag, NegFlag>; -def fms_volatile : Flag<["-"], "fms-volatile">, Group, - Visibility<[ClangOption, CC1Option]>, - MarshallingInfoFlag>; +defm ms_volatile : BoolFOption<"ms-volatile", + LangOpts<"MSVolatile">, DefaultFalse, + PosFlag, + NegFlag>; def fmsc_version : Joined<["-"], "fmsc-version=">, Group, Visibility<[ClangOption, CLOption]>, HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">; @@ -5306,7 +5308,8 @@ def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[NoXarchOption]>, def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[NoXarchOption]>, HelpText<"Rewrite Legacy Objective-C source to C++">; -def rdynamic : Flag<["-"], "rdynamic">, Group; +def rdynamic : Flag<["-"], "rdynamic">, Group, + Visibility<[ClangOption, FlangOption]>; def resource_dir : Separate<["-"], "resource-dir">, Flags<[NoXarchOption, HelpHidden]>, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, @@ -6997,6 +7000,8 @@ def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">, Values<"a_key,b_key">; def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">, MarshallingInfoFlag>; +def mbranch_protection_pauth_lr : Flag<["-"], "mbranch-protection-pauth-lr">, + MarshallingInfoFlag>; def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">, MarshallingInfoNegativeFlag>; def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, @@ -8217,7 +8222,7 @@ def _SLASH_winsysroot : CLJoinedOrSeparate<"winsysroot">, HelpText<"Same as \"/diasdkdir /DIA SDK\" /vctoolsdir /VC/Tools/MSVC/ \"/winsdkdir /Windows Kits/10\"">, MetaVarName<"">; def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, - Group<_SLASH_volatile_Group>, Flags<[NoXarchOption]>, Visibility<[CLOption]>, + Visibility<[CLOption]>, Alias, HelpText<"Volatile loads and stores have standard semantics">; def _SLASH_vmb : CLFlag<"vmb">, HelpText<"Use a best-case representation method for member pointers">; @@ -8232,7 +8237,7 @@ def _SLASH_vmv : CLFlag<"vmv">, HelpText<"Set the default most-general representation to " "virtual inheritance">; def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, - Group<_SLASH_volatile_Group>, Flags<[NoXarchOption]>, Visibility<[CLOption]>, + Visibility<[CLOption]>, Alias, HelpText<"Volatile loads and stores have acquire and release semantics">; def _SLASH_clang : CLJoined<"clang:">, HelpText<"Pass to the clang driver">, MetaVarName<"">; diff --git a/clang/include/clang/Interpreter/CodeCompletion.h b/clang/include/clang/Interpreter/CodeCompletion.h index 9adcdf0dc3afac6c9715668b39a8aae794986d6d..c64aa899759fd8796a7018e7e5f488c79144c01d 100644 --- a/clang/include/clang/Interpreter/CodeCompletion.h +++ b/clang/include/clang/Interpreter/CodeCompletion.h @@ -23,8 +23,27 @@ namespace clang { class CodeCompletionResult; class CompilerInstance; -void codeComplete(CompilerInstance *InterpCI, llvm::StringRef Content, - unsigned Line, unsigned Col, const CompilerInstance *ParentCI, - std::vector &CCResults); +struct ReplCodeCompleter { + ReplCodeCompleter() = default; + std::string Prefix; + + /// \param InterpCI [in] The compiler instance that is used to trigger code + /// completion + + /// \param Content [in] The string where code completion is triggered. + + /// \param Line [in] The line number of the code completion point. + + /// \param Col [in] The column number of the code completion point. + + /// \param ParentCI [in] The running interpreter compiler instance that + /// provides ASTContexts. + + /// \param CCResults [out] The completion results. + void codeComplete(CompilerInstance *InterpCI, llvm::StringRef Content, + unsigned Line, unsigned Col, + const CompilerInstance *ParentCI, + std::vector &CCResults); +}; } // namespace clang #endif diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 43573fb1a4b89151097ae8215c1fd0130edbb4c7..01858dfcc90ac5a78c1d47b952ca845d33c6e644 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -101,6 +101,7 @@ public: const ASTContext &getASTContext() const; ASTContext &getASTContext(); const CompilerInstance *getCompilerInstance() const; + CompilerInstance *getCompilerInstance(); llvm::Expected getExecutionEngine(); llvm::Expected Parse(llvm::StringRef Code); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1d7b4c729ce84e0968f78d5250c70438e86e927a..5e3b57ea33220b42906b17584b032a2fcaddf78d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2102,7 +2102,7 @@ public: SourceLocation AttrLoc); CodeAlignAttr *BuildCodeAlignAttr(const AttributeCommonInfo &CI, Expr *E); - bool CheckRebuiltCodeAlignStmtAttributes(ArrayRef Attrs); + bool CheckRebuiltStmtAttributes(ArrayRef Attrs); bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc); @@ -4799,8 +4799,6 @@ public: bool CheckAlwaysInlineAttr(const Stmt *OrigSt, const Stmt *CurSt, const AttributeCommonInfo &A); - bool CheckCountedByAttr(Scope *Scope, const FieldDecl *FD); - /// Adjust the calling convention of a method to be the ABI default if it /// wasn't specified explicitly. This handles method types formed from /// function type typedefs and typename template arguments. @@ -5644,7 +5642,6 @@ public: CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, ArrayRef Args = std::nullopt, - DeclContext *LookupCtx = nullptr, TypoExpr **Out = nullptr); DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, @@ -9357,8 +9354,7 @@ public: QualType DeduceTemplateSpecializationFromInitializer( TypeSourceInfo *TInfo, const InitializedEntity &Entity, - const InitializationKind &Kind, MultiExprArg Init, - ParenListExpr *PL = nullptr); + const InitializationKind &Kind, MultiExprArg Init); QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, @@ -13851,6 +13847,7 @@ private: bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool ParseSVEImmChecks(CallExpr *TheCall, SmallVector, 3> &ImmChecks); + bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, diff --git a/clang/include/clang/Sema/TypoCorrection.h b/clang/include/clang/Sema/TypoCorrection.h index 09de164297e7baa982ef75db617647bd5d92b528..e0f8d152dbe5545a56055ec2b554c0a37e93b889 100644 --- a/clang/include/clang/Sema/TypoCorrection.h +++ b/clang/include/clang/Sema/TypoCorrection.h @@ -282,7 +282,7 @@ class CorrectionCandidateCallback { public: static const unsigned InvalidDistance = TypoCorrection::InvalidDistance; - explicit CorrectionCandidateCallback(const IdentifierInfo *Typo = nullptr, + explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr, NestedNameSpecifier *TypoNNS = nullptr) : Typo(Typo), TypoNNS(TypoNNS) {} @@ -319,7 +319,7 @@ public: /// this method. virtual std::unique_ptr clone() = 0; - void setTypoName(const IdentifierInfo *II) { Typo = II; } + void setTypoName(IdentifierInfo *II) { Typo = II; } void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; } // Flags for context-dependent keywords. WantFunctionLikeCasts is only @@ -345,13 +345,13 @@ protected: candidate.getCorrectionSpecifier() == TypoNNS; } - const IdentifierInfo *Typo; + IdentifierInfo *Typo; NestedNameSpecifier *TypoNNS; }; class DefaultFilterCCC final : public CorrectionCandidateCallback { public: - explicit DefaultFilterCCC(const IdentifierInfo *Typo = nullptr, + explicit DefaultFilterCCC(IdentifierInfo *Typo = nullptr, NestedNameSpecifier *TypoNNS = nullptr) : CorrectionCandidateCallback(Typo, TypoNNS) {} @@ -365,10 +365,6 @@ public: template class DeclFilterCCC final : public CorrectionCandidateCallback { public: - explicit DeclFilterCCC(const IdentifierInfo *Typo = nullptr, - NestedNameSpecifier *TypoNNS = nullptr) - : CorrectionCandidateCallback(Typo, TypoNNS) {} - bool ValidateCandidate(const TypoCorrection &candidate) override { return candidate.getCorrectionDeclAs(); } diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 9bb89ec9410911afb362830ffdd35ff1059af899..21d791f5cd89a2ea983a6e29804529a56e9495a2 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1424,7 +1424,7 @@ private: RecordLocation TypeCursorForIndex(unsigned Index); void LoadedDecl(unsigned Index, Decl *D); Decl *ReadDeclRecord(serialization::DeclID ID); - void markIncompleteDeclChain(Decl *Canon); + void markIncompleteDeclChain(Decl *D); /// Returns the most recent declaration of a declaration (which must be /// of a redeclarable kind) that is either local or has already been loaded @@ -2093,7 +2093,7 @@ public: SmallVectorImpl> &Sels) override; void ReadWeakUndeclaredIdentifiers( - SmallVectorImpl> &WI) override; + SmallVectorImpl> &WeakIDs) override; void ReadUsedVTables(SmallVectorImpl &VTables) override; @@ -2203,7 +2203,7 @@ public: /// Retrieve the global selector ID that corresponds to this /// the local selector ID in a given module. - serialization::SelectorID getGlobalSelectorID(ModuleFile &F, + serialization::SelectorID getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const; /// Read the contents of a CXXCtorInitializer array. @@ -2422,6 +2422,8 @@ public: CurrentBitsIndex = 0; } + void advance(uint32_t BitsWidth) { CurrentBitsIndex += BitsWidth; } + bool getNextBit() { assert(isValid()); return Value & (1 << CurrentBitsIndex++); diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index a56929ef0245ee9733e3d5afa80848837cc501fa..de69f99003d82709ca367fe6baf3e7fee1ce7ede 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -564,11 +564,25 @@ private: unsigned DeclEnumAbbrev = 0; unsigned DeclObjCIvarAbbrev = 0; unsigned DeclCXXMethodAbbrev = 0; + unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0; + unsigned DeclTemplateCXXMethodAbbrev = 0; + unsigned DeclMemberSpecializedCXXMethodAbbrev = 0; + unsigned DeclTemplateSpecializedCXXMethodAbbrev = 0; + unsigned DeclDependentSpecializationCXXMethodAbbrev = 0; + unsigned DeclTemplateTypeParmAbbrev = 0; + unsigned DeclUsingShadowAbbrev = 0; unsigned DeclRefExprAbbrev = 0; unsigned CharacterLiteralAbbrev = 0; unsigned IntegerLiteralAbbrev = 0; unsigned ExprImplicitCastAbbrev = 0; + unsigned BinaryOperatorAbbrev = 0; + unsigned CompoundAssignOperatorAbbrev = 0; + unsigned CallExprAbbrev = 0; + unsigned CXXOperatorCallExprAbbrev = 0; + unsigned CXXMemberCallExprAbbrev = 0; + + unsigned CompoundStmtAbbrev = 0; void WriteDeclAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); @@ -735,12 +749,41 @@ public: unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; } unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; } unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; } - unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; } + unsigned getDeclCXXMethodAbbrev(FunctionDecl::TemplatedKind Kind) const { + switch (Kind) { + case FunctionDecl::TK_NonTemplate: + return DeclCXXMethodAbbrev; + case FunctionDecl::TK_FunctionTemplate: + return DeclTemplateCXXMethodAbbrev; + case FunctionDecl::TK_MemberSpecialization: + return DeclMemberSpecializedCXXMethodAbbrev; + case FunctionDecl::TK_FunctionTemplateSpecialization: + return DeclTemplateSpecializedCXXMethodAbbrev; + case FunctionDecl::TK_DependentNonTemplate: + return DeclDependentNonTemplateCXXMethodAbbrev; + case FunctionDecl::TK_DependentFunctionTemplateSpecialization: + return DeclDependentSpecializationCXXMethodAbbrev; + } + llvm_unreachable("Unknwon Template Kind!"); + } + unsigned getDeclTemplateTypeParmAbbrev() const { + return DeclTemplateTypeParmAbbrev; + } + unsigned getDeclUsingShadowAbbrev() const { return DeclUsingShadowAbbrev; } unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; } unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; } unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; } unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; } + unsigned getBinaryOperatorAbbrev() const { return BinaryOperatorAbbrev; } + unsigned getCompoundAssignOperatorAbbrev() const { + return CompoundAssignOperatorAbbrev; + } + unsigned getCallExprAbbrev() const { return CallExprAbbrev; } + unsigned getCXXOperatorCallExprAbbrev() { return CXXOperatorCallExprAbbrev; } + unsigned getCXXMemberCallExprAbbrev() { return CXXMemberCallExprAbbrev; } + + unsigned getCompoundStmtAbbrev() const { return CompoundStmtAbbrev; } bool hasChain() const { return Chain; } ASTReader *getChain() const { return Chain; } @@ -841,46 +884,33 @@ public: BitsPacker(BitsPacker &&) = delete; BitsPacker operator=(const BitsPacker &) = delete; BitsPacker operator=(BitsPacker &&) = delete; - ~BitsPacker() { - assert(!hasUnconsumedValues() && "There are unprocessed bits!"); + ~BitsPacker() = default; + + bool canWriteNextNBits(uint32_t BitsWidth) const { + return CurrentBitIndex + BitsWidth < BitIndexUpbound; + } + + void reset(uint32_t Value) { + UnderlyingValue = Value; + CurrentBitIndex = 0; } void addBit(bool Value) { addBits(Value, 1); } void addBits(uint32_t Value, uint32_t BitsWidth) { assert(BitsWidth < BitIndexUpbound); assert((Value < (1u << BitsWidth)) && "Passing narrower bit width!"); + assert(canWriteNextNBits(BitsWidth) && + "Inserting too much bits into a value!"); - if (CurrentBitIndex + BitsWidth >= BitIndexUpbound) { - Values.push_back(0); - CurrentBitIndex = 0; - } - - assert(CurrentBitIndex < BitIndexUpbound); - Values.back() |= Value << CurrentBitIndex; + UnderlyingValue |= Value << CurrentBitIndex; CurrentBitIndex += BitsWidth; } - bool hasUnconsumedValues() const { - return ConsumingValueIndex < Values.size(); - } - uint32_t getNextValue() { - assert(hasUnconsumedValues()); - return Values[ConsumingValueIndex++]; - } - - // We can convert the packer to an uint32_t if there is only one values. - operator uint32_t() { - assert(Values.size() == 1); - return getNextValue(); - } + operator uint32_t() { return UnderlyingValue; } private: - SmallVector Values; - uint16_t ConsumingValueIndex = 0; - // Initialize CurrentBitIndex with an invalid value - // to make it easier to update Values. See the implementation - // of `addBits` to see the details. - uint16_t CurrentBitIndex = BitIndexUpbound; + uint32_t UnderlyingValue = 0; + uint32_t CurrentBitIndex = 0; }; } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index a947bd0867025c2087a6278d3c13b2cbda33bba1..276d11e80a5b21c78acd293650fadeddcf4bd1c3 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -409,8 +409,8 @@ AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) { }; std::vector Checkers; for (StringRef CheckerName : StaticAnalyzerCheckerNames) { - if (!CheckerName.startswith("debug.") && - (IncludeExperimental || !CheckerName.startswith("alpha."))) + if (!CheckerName.starts_with("debug.") && + (IncludeExperimental || !CheckerName.starts_with("alpha."))) Checkers.push_back(CheckerName); } return Checkers; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 8956552e7bfc21e4c0f46ecbb7e0285f0bb6f032..e762f7548e0b54186883f140bcc793378913a67b 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -19,6 +19,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Preprocessor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" @@ -594,6 +595,9 @@ private: /// A vector of BugReports for tracking the allocated pointers and cleanup. std::vector EQClassesVector; + /// User-provided in-code suppressions. + BugSuppression UserSuppressions; + public: BugReporter(BugReporterData &d); virtual ~BugReporter(); diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h new file mode 100644 index 0000000000000000000000000000000000000000..4fd81b6275197446f3cf40acc1ef36ed9cc22dff --- /dev/null +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h @@ -0,0 +1,53 @@ +//===- BugSuppression.h - Suppression interface -----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines BugSuppression, a simple interface class encapsulating +// all user provided in-code suppressions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_SUPPRESSION_H +#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_SUPPRESSION_H + +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" + +namespace clang { +class Decl; + +namespace ento { +class BugReport; +class PathDiagnosticLocation; + +class BugSuppression { +public: + using DiagnosticIdentifierList = llvm::ArrayRef; + + /// Return true if the given bug report was explicitly suppressed by the user. + bool isSuppressed(const BugReport &); + + /// Return true if the bug reported at the given location was explicitly + /// suppressed by the user. + bool isSuppressed(const PathDiagnosticLocation &Location, + const Decl *DeclWithIssue, + DiagnosticIdentifierList DiagnosticIdentification); + +private: + // Overly pessimistic number, to be honest. + static constexpr unsigned EXPECTED_NUMBER_OF_SUPPRESSIONS = 8; + using CachedRanges = + llvm::SmallVector; + + llvm::DenseMap CachedSuppressionLocations; +}; + +} // end namespace ento +} // end namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_SUPPRESSION_H diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h index 5d2c96e5bc9de320c0cc60ec6f6c376a0deda6a0..45187433c069fd317480b861dbcb07ceb9fc38ea 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h @@ -13,6 +13,7 @@ namespace clang { namespace ento { namespace categories { +extern const char *const AppleAPIMisuse; extern const char *const CoreFoundationObjectiveC; extern const char *const LogicError; extern const char *const MemoryRefCount; diff --git a/clang/include/clang/StaticAnalyzer/Core/Checker.h b/clang/include/clang/StaticAnalyzer/Core/Checker.h index 8a46282a595eaed060eec1f264297b69e7ed802a..2ec54a837c42c96de38d3f56d81c1114ba5de37f 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -193,9 +193,8 @@ public: class Location { template - static void _checkLocation(void *checker, - const SVal &location, bool isLoad, const Stmt *S, - CheckerContext &C) { + static void _checkLocation(void *checker, SVal location, bool isLoad, + const Stmt *S, CheckerContext &C) { ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C); } @@ -209,8 +208,7 @@ public: class Bind { template - static void _checkBind(void *checker, - const SVal &location, const SVal &val, const Stmt *S, + static void _checkBind(void *checker, SVal location, SVal val, const Stmt *S, CheckerContext &C) { ((const CHECKER *)checker)->checkBind(location, val, S, C); } @@ -456,10 +454,8 @@ namespace eval { class Assume { template - static ProgramStateRef _evalAssume(void *checker, - ProgramStateRef state, - const SVal &cond, - bool assumption) { + static ProgramStateRef _evalAssume(void *checker, ProgramStateRef state, + SVal cond, bool assumption) { return ((const CHECKER *)checker)->evalAssume(state, cond, assumption); } diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 39583c443eda541fd3e0acb7053bf7d1118795c2..a45ba1bc573e1e0d7ab5b416af5595bf4615497e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -488,13 +488,11 @@ public: using CheckCallFunc = CheckerFn; - using CheckLocationFunc = - CheckerFn; + using CheckLocationFunc = CheckerFn; using CheckBindFunc = - CheckerFn; + CheckerFn; using CheckEndAnalysisFunc = CheckerFn; @@ -530,8 +528,7 @@ public: RegionAndSymbolInvalidationTraits *ITraits)>; using EvalAssumeFunc = - CheckerFn; + CheckerFn; using EvalCallFunc = CheckerFn; diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h index 49ce32553da81eb1c45a18c12e366e7f914b6885..c525d3443331e0b1ae415f63bcdb7a8d12b9680d 100644 --- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -485,7 +485,7 @@ public: // RVVRequire should be sync'ed with target features, but only // required features used in riscv_vector.td. -enum RVVRequire : uint16_t { +enum RVVRequire : uint32_t { RVV_REQ_None = 0, RVV_REQ_RV64 = 1 << 0, RVV_REQ_ZvfhminOrZvfh = 1 << 1, @@ -503,8 +503,9 @@ enum RVVRequire : uint16_t { RVV_REQ_Zvknhb = 1 << 13, RVV_REQ_Zvksed = 1 << 14, RVV_REQ_Zvksh = 1 << 15, + RVV_REQ_Experimental = 1 << 16, - LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Zvksh) + LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Experimental) }; // Raw RVV intrinsic info, used to expand later. @@ -536,7 +537,7 @@ struct RVVIntrinsicRecord { uint8_t OverloadedSuffixSize; // Required target features for this intrinsic. - uint16_t RequiredExtensions; + uint32_t RequiredExtensions; // Supported type, mask of BasicType. uint8_t TypeRangeMask; diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index ec1fb3ffa961c95cbfba635388ff19f8751401dc..d3aef09dac91056758e9b8d4abb0263bc710b71f 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -125,7 +125,7 @@ APINotesManager::loadAPINotes(StringRef Buffer) { bool APINotesManager::loadAPINotes(const DirectoryEntry *HeaderDir, FileEntryRef APINotesFile) { - assert(Readers.find(HeaderDir) == Readers.end()); + assert(!Readers.contains(HeaderDir)); if (auto Reader = loadAPINotes(APINotesFile)) { Readers[HeaderDir] = Reader.release(); return false; @@ -198,7 +198,7 @@ static void checkPrivateAPINotesName(DiagnosticsEngine &Diags, StringRef RealFileName = llvm::sys::path::filename(File->tryGetRealPathName()); StringRef RealStem = llvm::sys::path::stem(RealFileName); - if (RealStem.endswith("_private")) + if (RealStem.ends_with("_private")) return; unsigned DiagID = diag::warn_apinotes_private_case; diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index 4dfd01dae05f2ca8944b57d778de967e4f3b6533..57d6da7a1775960beec3ea1af7e26c5b905602c4 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -745,7 +745,7 @@ public: convertCommonEntity(M, MI, M.Selector); // Check if the selector ends with ':' to determine if it takes arguments. - bool takesArguments = M.Selector.endswith(":"); + bool takesArguments = M.Selector.ends_with(":"); // Split the selector into pieces. llvm::SmallVector Args; diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp index 8e398977dcd65d6ba25a17678961345f6fa842b5..b410d5f3b42a7eae63a838ee842637c376df02ba 100644 --- a/clang/lib/ARCMigrate/ARCMT.cpp +++ b/clang/lib/ARCMigrate/ARCMT.cpp @@ -201,7 +201,7 @@ createInvocationForMigration(CompilerInvocation &origCI, for (std::vector::iterator I = CInvok->getDiagnosticOpts().Warnings.begin(), E = CInvok->getDiagnosticOpts().Warnings.end(); I != E; ++I) { - if (!StringRef(*I).startswith("error")) + if (!StringRef(*I).starts_with("error")) WarnOpts.push_back(*I); } WarnOpts.push_back("error=arc-unsafe-retained-assign"); diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 5a25c88c65f64b4a1468dd6e681ea054b6b00ad3..ed363a46a2004439911a046271b10a34e04d3d02 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -562,7 +562,7 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) { if (ObjCCategoryDecl *CatDecl = dyn_cast(D)) { StringRef Name = CatDecl->getName(); - return Name.endswith("Deprecated"); + return Name.ends_with("Deprecated"); } return false; } @@ -1176,12 +1176,12 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, if (!SetterMethod) { // try a different naming convention for getter: isXxxxx StringRef getterNameString = getterName->getName(); - bool IsPrefix = getterNameString.startswith("is"); + bool IsPrefix = getterNameString.starts_with("is"); // Note that we don't want to change an isXXX method of retainable object // type to property (readonly or otherwise). if (IsPrefix && GRT->isObjCRetainableType()) return false; - if (IsPrefix || getterNameString.startswith("get")) { + if (IsPrefix || getterNameString.starts_with("get")) { LengthOfPrefix = (IsPrefix ? 2 : 3); const char *CGetterName = getterNameString.data() + LengthOfPrefix; // Make sure that first character after "is" or "get" prefix can @@ -1320,11 +1320,11 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, if (OIT_Family == OIT_Singleton || OIT_Family == OIT_ReturnsSelf) { StringRef STRefMethodName(MethodName); size_t len = 0; - if (STRefMethodName.startswith("standard")) + if (STRefMethodName.starts_with("standard")) len = strlen("standard"); - else if (STRefMethodName.startswith("shared")) + else if (STRefMethodName.starts_with("shared")) len = strlen("shared"); - else if (STRefMethodName.startswith("default")) + else if (STRefMethodName.starts_with("default")) len = strlen("default"); else return; @@ -1341,7 +1341,7 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, StringRef LoweredMethodName(MethodName); std::string StringLoweredMethodName = LoweredMethodName.lower(); LoweredMethodName = StringLoweredMethodName; - if (!LoweredMethodName.startswith(ClassNamePostfix)) + if (!LoweredMethodName.starts_with(ClassNamePostfix)) return; if (OIT_Family == OIT_ReturnsSelf) ReplaceWithClasstype(*this, OM); diff --git a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp index 40220a2eef4910be7630a481444ea71b3eb57b5d..1e6354f71e294a90cb7164255f67786bcbafd3c8 100644 --- a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -146,7 +146,7 @@ private: ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF", FD->getIdentifier()->getName())) { StringRef fname = FD->getIdentifier()->getName(); - if (fname.endswith("Retain") || fname.contains("Create") || + if (fname.ends_with("Retain") || fname.contains("Create") || fname.contains("Copy")) { // Do not migrate to couple of bridge transfer casts which // cancel each other out. Leave it unchanged so error gets user diff --git a/clang/lib/ARCMigrate/TransformActions.cpp b/clang/lib/ARCMigrate/TransformActions.cpp index bd5c793568671d7a4ad814d9ac6d7f57285ffcda..6bc6fed1a9032013a14f5faa54a74d7dddf7e9a5 100644 --- a/clang/lib/ARCMigrate/TransformActions.cpp +++ b/clang/lib/ARCMigrate/TransformActions.cpp @@ -431,7 +431,7 @@ bool TransformActionsImpl::canReplaceText(SourceLocation loc, StringRef text) { if (invalidTemp) return false; - return file.substr(locInfo.second).startswith(text); + return file.substr(locInfo.second).starts_with(text); } void TransformActionsImpl::commitInsert(SourceLocation loc, StringRef text) { diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp index 90b2b32b6b1be24865602a533677ab5afad27466..2808e35135dc358c832f87715a8d699e5c0e6242 100644 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ b/clang/lib/ARCMigrate/Transforms.cpp @@ -95,7 +95,7 @@ bool trans::isPlusOne(const Expr *E) { ento::cocoa::isRefType(callE->getType(), "CF", FD->getIdentifier()->getName())) { StringRef fname = FD->getIdentifier()->getName(); - if (fname.endswith("Retain") || fname.contains("Create") || + if (fname.ends_with("Retain") || fname.contains("Create") || fname.contains("Copy")) return true; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index e877f903b34c6bbbb1089231aec07494e1acf0c2..0395b3e47ab6f8f4b4aab79cb14231709c1572c1 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8223,7 +8223,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, // Another legacy compatibility encoding. Some ObjC qualifier and type // combinations need to be rearranged. // Rewrite "in const" from "nr" to "rn" - if (StringRef(S).endswith("nr")) + if (StringRef(S).ends_with("nr")) S.replace(S.end()-2, S.end(), "rn"); } @@ -13519,7 +13519,7 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap, Target->getTargetOpts().FeaturesAsWritten.begin(), Target->getTargetOpts().FeaturesAsWritten.end()); } else { - if (VersionStr.startswith("arch=")) + if (VersionStr.starts_with("arch=")) TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1); else if (VersionStr != "default") Features.push_back((StringRef{"+"} + VersionStr).str()); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index f1f335118f37a4d1837f9b96fe148e6924bee292..b61180c4f3491da9f767d32c5c11bc059c79a7c9 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2771,9 +2771,11 @@ ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { for (auto *FoundDecl : FoundDecls) { if (!FoundDecl->isInIdentifierNamespace(IDNS)) continue; - if (auto *FoundAlias = dyn_cast(FoundDecl)) - return Importer.MapImported(D, FoundAlias); - ConflictingDecls.push_back(FoundDecl); + if (auto *FoundAlias = dyn_cast(FoundDecl)) { + if (IsStructuralMatch(D, FoundAlias)) + return Importer.MapImported(D, FoundAlias); + ConflictingDecls.push_back(FoundDecl); + } } if (!ConflictingDecls.empty()) { @@ -3418,10 +3420,16 @@ static bool isAncestorDeclContextOf(const DeclContext *DC, const Stmt *S) { while (!ToProcess.empty()) { const Stmt *CurrentS = ToProcess.pop_back_val(); ToProcess.append(CurrentS->child_begin(), CurrentS->child_end()); - if (const auto *DeclRef = dyn_cast(CurrentS)) + if (const auto *DeclRef = dyn_cast(CurrentS)) { if (const Decl *D = DeclRef->getDecl()) if (isAncestorDeclContextOf(DC, D)) return true; + } else if (const auto *E = + dyn_cast_or_null(CurrentS)) { + if (const Decl *D = E->getAssociatedDecl()) + if (isAncestorDeclContextOf(DC, D)) + return true; + } } return false; } @@ -7820,6 +7828,18 @@ ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) { *ToLParenLocOrErr, OCE->getBridgeKind(), E->getCastKind(), *ToBridgeKeywordLocOrErr, ToTypeInfoAsWritten, ToSubExpr); } + case Stmt::BuiltinBitCastExprClass: { + auto *BBC = cast(E); + ExpectedSLoc ToKWLocOrErr = import(BBC->getBeginLoc()); + if (!ToKWLocOrErr) + return ToKWLocOrErr.takeError(); + ExpectedSLoc ToRParenLocOrErr = import(BBC->getEndLoc()); + if (!ToRParenLocOrErr) + return ToRParenLocOrErr.takeError(); + return new (Importer.getToContext()) BuiltinBitCastExpr( + ToType, E->getValueKind(), E->getCastKind(), ToSubExpr, + ToTypeInfoAsWritten, *ToKWLocOrErr, *ToRParenLocOrErr); + } default: llvm_unreachable("Cast expression of unsupported type!"); return make_error(ASTImportError::UnsupportedConstruct); @@ -9003,10 +9023,6 @@ class AttrImporter { public: AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {} - // Useful for accessing the imported attribute. - template T *castAttrAs() { return cast(ToAttr); } - template const T *castAttrAs() const { return cast(ToAttr); } - // Create an "importer" for an attribute parameter. // Result of the 'value()' of that object is to be passed to the function // 'importAttr', in the order that is expected by the attribute class. @@ -9101,6 +9117,12 @@ Expected ASTImporter::Import(const Attr *FromAttr) { break; } + case attr::AlignValue: { + auto *From = cast(FromAttr); + AI.importAttr(From, AI.importArg(From->getAlignment()).value()); + break; + } + case attr::Format: { const auto *From = cast(FromAttr); AI.importAttr(From, Import(From->getType()), From->getFormatIdx(), @@ -9214,15 +9236,6 @@ Expected ASTImporter::Import(const Attr *FromAttr) { From->args_size()); break; } - case attr::CountedBy: { - AI.cloneAttr(FromAttr); - const auto *CBA = cast(FromAttr); - Expected SR = Import(CBA->getCountedByFieldLoc()).get(); - if (!SR) - return SR.takeError(); - AI.castAttrAs()->setCountedByFieldLoc(SR.get()); - break; - } default: { // The default branch works for attributes that have no arguments to import. @@ -9391,7 +9404,6 @@ Expected ASTImporter::Import(Decl *FromD) { setImportDeclError(FromD, *Error); return make_error(*Error); } - // Make sure that ImportImpl registered the imported decl. assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?"); if (auto Error = ImportAttrs(ToD, FromD)) diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 6bb4bf14b873d7bd041032fdcc2d4309f8b194d0..1f492b051e0341cf74edeb2839e9b0875eb3a577 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1977,6 +1977,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, D2->getTemplatedDecl()->getType()); } +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + TypeAliasTemplateDecl *D1, + TypeAliasTemplateDecl *D2) { + // Check template parameters. + if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2)) + return false; + + // Check the templated declaration. + return IsStructurallyEquivalent(Context, D1->getTemplatedDecl(), + D2->getTemplatedDecl()); +} + static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, ConceptDecl *D1, ConceptDecl *D2) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 527ea6042daa0344237ed90e46e8729520db2c3b..12e0a6faa4c33d184324bb1bfa26574ae32676e0 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1088,11 +1088,11 @@ bool NamedDecl::isPlaceholderVar(const LangOptions &LangOpts) const { return false; if (isa(this)) return true; - if (auto *IFD = dyn_cast(this)) { + if (const auto *IFD = dyn_cast(this)) { if (!getDeclContext()->isFunctionOrMethod() && !getDeclContext()->isRecord()) return false; - VarDecl *VD = IFD->getVarDecl(); + const VarDecl *VD = IFD->getVarDecl(); return !VD || VD->getStorageDuration() == SD_Automatic; } // and it declares a variable with automatic storage duration @@ -1105,7 +1105,7 @@ bool NamedDecl::isPlaceholderVar(const LangOptions &LangOpts) const { } if (const auto *BD = dyn_cast(this); BD && getDeclContext()->isFunctionOrMethod()) { - VarDecl *VD = BD->getHoldingVar(); + const VarDecl *VD = BD->getHoldingVar(); return !VD || VD->getStorageDuration() == StorageDuration::SD_Automatic; } return false; @@ -1843,7 +1843,8 @@ static bool isRedeclarable(Decl::Kind K) { llvm_unreachable("unknown decl kind"); } -bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { +bool NamedDecl::declarationReplaces(const NamedDecl *OldD, + bool IsKnownNewer) const { assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); // Never replace one imported declaration with another; we need both results @@ -1873,13 +1874,13 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { // Using declarations can be replaced if they import the same name from the // same context. - if (auto *UD = dyn_cast(this)) { + if (const auto *UD = dyn_cast(this)) { ASTContext &Context = getASTContext(); return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) == Context.getCanonicalNestedNameSpecifier( cast(OldD)->getQualifier()); } - if (auto *UUVD = dyn_cast(this)) { + if (const auto *UUVD = dyn_cast(this)) { ASTContext &Context = getASTContext(); return Context.getCanonicalNestedNameSpecifier(UUVD->getQualifier()) == Context.getCanonicalNestedNameSpecifier( @@ -1896,7 +1897,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { // Check whether this is actually newer than OldD. We want to keep the // newer declaration. This loop will usually only iterate once, because // OldD is usually the previous declaration. - for (auto *D : redecls()) { + for (const auto *D : redecls()) { if (D == OldD) break; @@ -2199,8 +2200,7 @@ static LanguageLinkage getDeclLanguageLinkage(const T &D) { // Language linkage is a C++ concept, but saying that everything else in C has // C language linkage fits the implementation nicely. - ASTContext &Context = D.getASTContext(); - if (!Context.getLangOpts().CPlusPlus) + if (!D.getASTContext().getLangOpts().CPlusPlus) return CLanguageLinkage; // C++ [dcl.link]p4: A C language linkage is ignored in determining the @@ -2943,7 +2943,7 @@ bool ParmVarDecl::isDestroyedInCallee() const { // FIXME: isParamDestroyedInCallee() should probably imply // isDestructedType() - auto *RT = getType()->getAs(); + const auto *RT = getType()->getAs(); if (RT && RT->getDecl()->isParamDestroyedInCallee() && getType().isDestructedType()) return true; @@ -3105,7 +3105,7 @@ FunctionDecl::getDefaultedFunctionInfo() const { } bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { - for (auto *I : redecls()) { + for (const auto *I : redecls()) { if (I->doesThisDeclarationHaveABody()) { Definition = I; return true; @@ -3116,7 +3116,7 @@ bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { } bool FunctionDecl::hasTrivialBody() const { - Stmt *S = getBody(); + const Stmt *S = getBody(); if (!S) { // Since we don't have a body for this function, we don't know if it's // trivial or not. @@ -3212,7 +3212,7 @@ void FunctionDecl::setPure(bool P) { template static bool isNamed(const NamedDecl *ND, const char (&Str)[Len]) { - IdentifierInfo *II = ND->getIdentifier(); + const IdentifierInfo *II = ND->getIdentifier(); return II && II->isStr(Str); } @@ -3305,9 +3305,9 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { if (proto->getNumParams() != 2 || proto->isVariadic()) return false; - ASTContext &Context = - cast(getDeclContext()->getRedeclContext()) - ->getASTContext(); + const ASTContext &Context = + cast(getDeclContext()->getRedeclContext()) + ->getASTContext(); // The result type and first argument type are constant across all // these operators. The second argument must be exactly void*. @@ -3342,7 +3342,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction( unsigned Params = 1; QualType Ty = FPT->getParamType(Params); - ASTContext &Ctx = getASTContext(); + const ASTContext &Ctx = getASTContext(); auto Consume = [&] { ++Params; @@ -3388,7 +3388,8 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction( QualType T = Ty; while (const auto *TD = T->getAs()) T = TD->getDecl()->getUnderlyingType(); - IdentifierInfo *II = T->castAs()->getDecl()->getIdentifier(); + const IdentifierInfo *II = + T->castAs()->getDecl()->getIdentifier(); if (II && II->isStr("__hot_cold_t")) Consume(); } @@ -3586,7 +3587,7 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { (!hasAttr() && !hasAttr())) return 0; - ASTContext &Context = getASTContext(); + const ASTContext &Context = getASTContext(); if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) return BuiltinID; @@ -3745,7 +3746,7 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { assert(!doesThisDeclarationHaveABody() && "Must have a declaration without a body."); - ASTContext &Context = getASTContext(); + const ASTContext &Context = getASTContext(); if (Context.getLangOpts().MSVCCompat) { const FunctionDecl *Definition; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index e4d7169752bc857e03a0d65aece37e5ed91b17cd..5e03f0223d311ced8383bbff2c965eee19b56003 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -29,6 +29,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/PartialDiagnostic.h" @@ -410,79 +411,6 @@ bool Decl::isFileContextDecl() const { return DC && DC->isFileContext(); } -bool Decl::isFlexibleArrayMemberLike( - ASTContext &Ctx, const Decl *D, QualType Ty, - LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, - bool IgnoreTemplateOrMacroSubstitution) { - // For compatibility with existing code, we treat arrays of length 0 or - // 1 as flexible array members. - const auto *CAT = Ctx.getAsConstantArrayType(Ty); - if (CAT) { - using FAMKind = LangOptions::StrictFlexArraysLevelKind; - - llvm::APInt Size = CAT->getSize(); - if (StrictFlexArraysLevel == FAMKind::IncompleteOnly) - return false; - - // GCC extension, only allowed to represent a FAM. - if (Size.isZero()) - return true; - - if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1)) - return false; - - if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2)) - return false; - } else if (!Ctx.getAsIncompleteArrayType(Ty)) { - return false; - } - - if (const auto *OID = dyn_cast_if_present(D)) - return OID->getNextIvar() == nullptr; - - const auto *FD = dyn_cast_if_present(D); - if (!FD) - return false; - - if (CAT) { - // GCC treats an array memeber of a union as an FAM if the size is one or - // zero. - llvm::APInt Size = CAT->getSize(); - if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne())) - return true; - } - - // Don't consider sizes resulting from macro expansions or template argument - // substitution to form C89 tail-padded arrays. - if (IgnoreTemplateOrMacroSubstitution) { - TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); - while (TInfo) { - TypeLoc TL = TInfo->getTypeLoc(); - - // Look through typedefs. - if (TypedefTypeLoc TTL = TL.getAsAdjusted()) { - const TypedefNameDecl *TDL = TTL.getTypedefNameDecl(); - TInfo = TDL->getTypeSourceInfo(); - continue; - } - - if (auto CTL = TL.getAs()) { - if (const Expr *SizeExpr = - dyn_cast_if_present(CTL.getSizeExpr()); - !SizeExpr || SizeExpr->getExprLoc().isMacroID()) - return false; - } - - break; - } - } - - // Test that the field is the last in the structure. - RecordDecl::field_iterator FI( - DeclContext::decl_iterator(const_cast(FD))); - return ++FI == FD->getParent()->field_end(); -} - TranslationUnitDecl *Decl::getTranslationUnitDecl() { if (auto *TUD = dyn_cast(this)) return TUD; diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 30a26d518386c52363645bd8ddb986c6696cbf9b..24da6f2ef32b4fc3c17d90e75b5bd4315c48d4e2 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1728,7 +1728,7 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T). getAsString(Policy); Out << ' ' << TypeStr; - if (!StringRef(TypeStr).endswith("*")) + if (!StringRef(TypeStr).ends_with("*")) Out << ' '; Out << *PDecl; if (Policy.PolishForDeclaration) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b125fc676da8419e737761b7db2a711df54adb46..a90f92d07f86d26b85a544a888487f5cc8169e72 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -205,22 +205,85 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const { } bool Expr::isFlexibleArrayMemberLike( - ASTContext &Ctx, + ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution) const { + + // For compatibility with existing code, we treat arrays of length 0 or + // 1 as flexible array members. + const auto *CAT = Context.getAsConstantArrayType(getType()); + if (CAT) { + llvm::APInt Size = CAT->getSize(); + + using FAMKind = LangOptions::StrictFlexArraysLevelKind; + + if (StrictFlexArraysLevel == FAMKind::IncompleteOnly) + return false; + + // GCC extension, only allowed to represent a FAM. + if (Size == 0) + return true; + + if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1)) + return false; + + if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2)) + return false; + } else if (!Context.getAsIncompleteArrayType(getType())) + return false; + const Expr *E = IgnoreParens(); - const Decl *D = nullptr; - if (const auto *ME = dyn_cast(E)) - D = ME->getMemberDecl(); - else if (const auto *DRE = dyn_cast(E)) - D = DRE->getDecl(); + const NamedDecl *ND = nullptr; + if (const auto *DRE = dyn_cast(E)) + ND = DRE->getDecl(); + else if (const auto *ME = dyn_cast(E)) + ND = ME->getMemberDecl(); else if (const auto *IRE = dyn_cast(E)) - D = IRE->getDecl(); + return IRE->getDecl()->getNextIvar() == nullptr; + + if (!ND) + return false; - return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(), - StrictFlexArraysLevel, - IgnoreTemplateOrMacroSubstitution); + // A flexible array member must be the last member in the class. + // FIXME: If the base type of the member expr is not FD->getParent(), + // this should not be treated as a flexible array member access. + if (const auto *FD = dyn_cast(ND)) { + // GCC treats an array memeber of a union as an FAM if the size is one or + // zero. + if (CAT) { + llvm::APInt Size = CAT->getSize(); + if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne())) + return true; + } + + // Don't consider sizes resulting from macro expansions or template argument + // substitution to form C89 tail-padded arrays. + if (IgnoreTemplateOrMacroSubstitution) { + TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); + while (TInfo) { + TypeLoc TL = TInfo->getTypeLoc(); + // Look through typedefs. + if (TypedefTypeLoc TTL = TL.getAsAdjusted()) { + const TypedefNameDecl *TDL = TTL.getTypedefNameDecl(); + TInfo = TDL->getTypeSourceInfo(); + continue; + } + if (ConstantArrayTypeLoc CTL = TL.getAs()) { + const Expr *SizeExpr = dyn_cast(CTL.getSizeExpr()); + if (!SizeExpr || SizeExpr->getExprLoc().isMacroID()) + return false; + } + break; + } + } + + RecordDecl::field_iterator FI( + DeclContext::decl_iterator(const_cast(FD))); + return ++FI == FD->getParent()->field_end(); + } + + return false; } const ValueDecl * diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index f7f8e6c73d84e21369343ff5eac81602a725480c..e6b3097a80d8f78994308057e8877c2e72648a70 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -222,6 +222,64 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitNE(PtrT, CE); } + case CK_IntegralComplexToBoolean: + case CK_FloatingComplexToBoolean: { + std::optional ElemT = + classifyComplexElementType(SubExpr->getType()); + if (!ElemT) + return false; + // We emit the expression (__real(E) != 0 || __imag(E) != 0) + // for us, that means (bool)E[0] || (bool)E[1] + if (!this->visit(SubExpr)) + return false; + if (!this->emitConstUint8(0, CE)) + return false; + if (!this->emitArrayElemPtrUint8(CE)) + return false; + if (!this->emitLoadPop(*ElemT, CE)) + return false; + if (*ElemT == PT_Float) { + if (!this->emitCastFloatingIntegral(PT_Bool, CE)) + return false; + } else { + if (!this->emitCast(*ElemT, PT_Bool, CE)) + return false; + } + + // We now have the bool value of E[0] on the stack. + LabelTy LabelTrue = this->getLabel(); + if (!this->jumpTrue(LabelTrue)) + return false; + + if (!this->emitConstUint8(1, CE)) + return false; + if (!this->emitArrayElemPtrPopUint8(CE)) + return false; + if (!this->emitLoadPop(*ElemT, CE)) + return false; + if (*ElemT == PT_Float) { + if (!this->emitCastFloatingIntegral(PT_Bool, CE)) + return false; + } else { + if (!this->emitCast(*ElemT, PT_Bool, CE)) + return false; + } + // Leave the boolean value of E[1] on the stack. + LabelTy EndLabel = this->getLabel(); + this->jump(EndLabel); + + this->emitLabel(LabelTrue); + if (!this->emitPopPtr(CE)) + return false; + if (!this->emitConstBool(true, CE)) + return false; + + this->fallthrough(EndLabel); + this->emitLabel(EndLabel); + + return true; + } + case CK_ToVoid: return discard(SubExpr); @@ -258,6 +316,9 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { if (BO->isLogicalOp()) return this->VisitLogicalBinOp(BO); + if (BO->getType()->isAnyComplexType()) + return this->VisitComplexBinOp(BO); + const Expr *LHS = BO->getLHS(); const Expr *RHS = BO->getRHS(); @@ -500,6 +561,107 @@ bool ByteCodeExprGen::VisitLogicalBinOp(const BinaryOperator *E) { return true; } +template +bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) { + assert(Initializing); + + const Expr *LHS = E->getLHS(); + const Expr *RHS = E->getRHS(); + PrimType LHSElemT = *this->classifyComplexElementType(LHS->getType()); + PrimType RHSElemT = *this->classifyComplexElementType(RHS->getType()); + + unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false); + unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false); + unsigned ResultOffset = ~0u; + if (!this->DiscardResult) + ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false); + + assert(LHSElemT == RHSElemT); + + // Save result pointer in ResultOffset + if (!this->DiscardResult) { + if (!this->emitDupPtr(E)) + return false; + if (!this->emitSetLocal(PT_Ptr, ResultOffset, E)) + return false; + } + + // Evaluate LHS and save value to LHSOffset. + if (!this->visit(LHS)) + return false; + if (!this->emitSetLocal(PT_Ptr, LHSOffset, E)) + return false; + + // Same with RHS. + if (!this->visit(RHS)) + return false; + if (!this->emitSetLocal(PT_Ptr, RHSOffset, E)) + return false; + + // Now we can get pointers to the LHS and RHS from the offsets above. + BinaryOperatorKind Op = E->getOpcode(); + for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) { + // Result pointer for the store later. + if (!this->DiscardResult) { + if (!this->emitGetLocal(PT_Ptr, ResultOffset, E)) + return false; + } + + if (!this->emitGetLocal(PT_Ptr, LHSOffset, E)) + return false; + if (!this->emitConstUint8(ElemIndex, E)) + return false; + if (!this->emitArrayElemPtrPopUint8(E)) + return false; + if (!this->emitLoadPop(LHSElemT, E)) + return false; + + if (!this->emitGetLocal(PT_Ptr, RHSOffset, E)) + return false; + if (!this->emitConstUint8(ElemIndex, E)) + return false; + if (!this->emitArrayElemPtrPopUint8(E)) + return false; + if (!this->emitLoadPop(RHSElemT, E)) + return false; + + // The actual operation. + switch (Op) { + case BO_Add: + if (LHSElemT == PT_Float) { + if (!this->emitAddf(getRoundingMode(E), E)) + return false; + } else { + if (!this->emitAdd(LHSElemT, E)) + return false; + } + break; + case BO_Sub: + if (LHSElemT == PT_Float) { + if (!this->emitSubf(getRoundingMode(E), E)) + return false; + } else { + if (!this->emitSub(LHSElemT, E)) + return false; + } + break; + + default: + return false; + } + + if (!this->DiscardResult) { + // Initialize array element with the value we just computed. + if (!this->emitInitElemPop(LHSElemT, ElemIndex, E)) + return false; + } else { + if (!this->emitPop(LHSElemT, E)) + return false; + } + } + return true; +} + template bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { QualType QT = E->getType(); @@ -671,6 +833,32 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { return true; } + if (T->isAnyComplexType()) { + unsigned NumInits = E->getNumInits(); + QualType ElemQT = E->getType()->getAs()->getElementType(); + PrimType ElemT = classifyPrim(ElemQT); + if (NumInits == 0) { + // Zero-initialize both elements. + for (unsigned I = 0; I < 2; ++I) { + if (!this->visitZeroInitializer(ElemT, ElemQT, E)) + return false; + if (!this->emitInitElem(ElemT, I, E)) + return false; + } + } else if (NumInits == 2) { + unsigned InitIndex = 0; + for (const Expr *Init : E->inits()) { + if (!this->visit(Init)) + return false; + + if (!this->emitInitElem(ElemT, InitIndex, E)) + return false; + ++InitIndex; + } + } + return true; + } + return false; } @@ -1647,7 +1835,8 @@ template bool ByteCodeExprGen::visit(const Expr *E) { return this->discard(E); // Create local variable to hold the return value. - if (!E->isGLValue() && !classify(E->getType())) { + if (!E->isGLValue() && !E->getType()->isAnyComplexType() && + !classify(E->getType())) { std::optional LocalIndex = allocateLocal(E, /*IsExtended=*/true); if (!LocalIndex) return false; @@ -1833,6 +2022,9 @@ bool ByteCodeExprGen::dereference( return Indirect(*T); } + if (LV->getType()->isAnyComplexType()) + return visit(LV); + return false; } @@ -2092,15 +2284,33 @@ const Function *ByteCodeExprGen::getFunction(const FunctionDecl *FD) { template bool ByteCodeExprGen::visitExpr(const Expr *E) { ExprScope RootScope(this); - if (!visit(E)) - return false; - - if (E->getType()->isVoidType()) + // Void expressions. + if (E->getType()->isVoidType()) { + if (!visit(E)) + return false; return this->emitRetVoid(E); + } - if (std::optional T = classify(E)) + // Expressions with a primitive return type. + if (std::optional T = classify(E)) { + if (!visit(E)) + return false; return this->emitRet(*T, E); - return this->emitRetValue(E); + } + + // Expressions with a composite return type. + // For us, that means everything we don't + // have a PrimType for. + if (std::optional LocalOffset = this->allocateLocal(E)) { + if (!this->visitLocalInitializer(E, *LocalOffset)) + return false; + + if (!this->emitGetPtrLocal(*LocalOffset, E)) + return false; + return this->emitRetValue(E); + } + + return false; } /// Toplevel visitDecl(). @@ -2550,8 +2760,36 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { if (!this->visit(SubExpr)) return false; return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E); - case UO_Real: // __real x - case UO_Imag: // __imag x + case UO_Real: { // __real x + assert(!T); + if (!this->visit(SubExpr)) + return false; + if (!this->emitConstUint8(0, E)) + return false; + if (!this->emitArrayElemPtrPopUint8(E)) + return false; + + // Since our _Complex implementation does not map to a primitive type, + // we sometimes have to do the lvalue-to-rvalue conversion here manually. + if (!SubExpr->isLValue()) + return this->emitLoadPop(classifyPrim(E->getType()), E); + return true; + } + case UO_Imag: { // __imag x + assert(!T); + if (!this->visit(SubExpr)) + return false; + if (!this->emitConstUint8(1, E)) + return false; + if (!this->emitArrayElemPtrPopUint8(E)) + return false; + + // Since our _Complex implementation does not map to a primitive type, + // we sometimes have to do the lvalue-to-rvalue conversion here manually. + if (!SubExpr->isLValue()) + return this->emitLoadPop(classifyPrim(E->getType()), E); + return true; + } case UO_Extension: return this->delegate(SubExpr); case UO_Coawait: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index bc1d5d11a1151356e75620d448d0627ff60ba9a0..bbb13e97e725692237f5388936012e9a24a28cbd 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -65,6 +65,7 @@ public: bool VisitBinaryOperator(const BinaryOperator *E); bool VisitLogicalBinOp(const BinaryOperator *E); bool VisitPointerArithBinOp(const BinaryOperator *E); + bool VisitComplexBinOp(const BinaryOperator *E); bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E); bool VisitCallExpr(const CallExpr *E); bool VisitBuiltinCallExpr(const CallExpr *E); @@ -285,6 +286,14 @@ private: } bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E); + std::optional classifyComplexElementType(QualType T) const { + assert(T->isAnyComplexType()); + + QualType ElemType = T->getAs()->getElementType(); + + return this->classify(ElemType); + } + bool emitRecordDestruction(const Descriptor *Desc); unsigned collectBaseOffset(const RecordType *BaseType, const RecordType *DerivedType); diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 4fe6d1173f427e7923a91bb5e944c2cf45e37ed5..17abb71635839c794b2511a6e2bde2dfa7899f80 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -92,6 +92,9 @@ std::optional Context::classify(QualType T) const { if (T->isBooleanType()) return PT_Bool; + if (T->isAnyComplexType()) + return std::nullopt; + if (T->isSignedIntegerOrEnumerationType()) { switch (Ctx.getIntWidth(T)) { case 64: diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index 9bc42057c5f57822ed6cf980f7aaa1b14adbf2c9..0ff0bde8fd17e85b14babdc06995e034a99e8c96 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -208,6 +208,27 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) { } return Ok; } + + // Complex types. + if (const auto *CT = Ty->getAs()) { + QualType ElemTy = CT->getElementType(); + std::optional ElemT = Ctx.classify(ElemTy); + assert(ElemT); + + if (ElemTy->isIntegerType()) { + INT_TYPE_SWITCH(*ElemT, { + auto V1 = Ptr.atIndex(0).deref(); + auto V2 = Ptr.atIndex(1).deref(); + Result = APValue(V1.toAPSInt(), V2.toAPSInt()); + return true; + }); + } else if (ElemTy->isFloatingType()) { + Result = APValue(Ptr.atIndex(0).deref().getAPFloat(), + Ptr.atIndex(1).deref().getAPFloat()); + return true; + } + return false; + } llvm_unreachable("invalid value to return"); }; diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 13b77e9a87725c73efd19346cafde1f43728bd9c..a82d1c3c7c622a3db101443ed6fc8aa5d144f51d 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -350,11 +350,6 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { } if (!F->isConstexpr()) { - // Don't emit anything if we're checking for a potential constant - // expression. That will happen later when actually executing. - if (S.checkingPotentialConstantExpression()) - return false; - const SourceLocation &Loc = S.Current->getLocation(OpPC); if (S.getLangOpts().CPlusPlus11) { const FunctionDecl *DiagDecl = F->getDecl(); @@ -371,13 +366,21 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { // FIXME: If DiagDecl is an implicitly-declared special member function // or an inheriting constructor, we should be much more explicit about why // it's not constexpr. - if (CD && CD->isInheritingConstructor()) + if (CD && CD->isInheritingConstructor()) { S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1) << CD->getInheritedConstructor().getConstructor()->getParent(); - else + S.Note(DiagDecl->getLocation(), diag::note_declared_at); + } else { + // Don't emit anything if the function isn't defined and we're checking + // for a constant expression. It might be defined at the point we're + // actually calling it. + if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression()) + return false; + S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; - S.Note(DiagDecl->getLocation(), diag::note_declared_at); + S.Note(DiagDecl->getLocation(), diag::note_declared_at); + } } else { S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr); } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index a240d74d63425e813859d1248aac5e603de8651a..828d4ea35526d6c5261eb1b264afc306c394318f 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -37,7 +37,6 @@ namespace clang { namespace interp { -using APInt = llvm::APInt; using APSInt = llvm::APSInt; /// Convert a value to an APValue. diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp index 64c971912a91d073328c835523430be6b36e1ac2..d3a6b61fd2bec9c659b24c4ab995f4459254d54f 100644 --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -147,7 +147,7 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) { // If the label isn't literal, or if this is an alias for an LLVM intrinsic, // do not add a "\01" prefix. - if (!ALA->getIsLiteralLabel() || ALA->getLabel().startswith("llvm.")) { + if (!ALA->getIsLiteralLabel() || ALA->getLabel().starts_with("llvm.")) { Out << ALA->getLabel(); return; } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index c59a66e103a6e3b929fa950f93414bd58c185de0..8346ad87b409b6196126164086468673b0ca48c4 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -63,7 +63,7 @@ struct msvc_hashing_ostream : public llvm::raw_svector_ostream { : llvm::raw_svector_ostream(Buffer), OS(OS) {} ~msvc_hashing_ostream() override { StringRef MangledName = str(); - bool StartsWithEscape = MangledName.startswith("\01"); + bool StartsWithEscape = MangledName.starts_with("\01"); if (StartsWithEscape) MangledName = MangledName.drop_front(1); if (MangledName.size() < 4096) { diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index f0b9d0ecaf23461ac1b846a45cb39dab0257cf1b..3b09ca40bd2a53e99f50ea8bb805e4e56bb6c4f9 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -140,7 +140,7 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, // Set the privacy flag if the privacy annotation in the // comma-delimited segment is at least as strict as the privacy // annotations in previous comma-delimited segments. - if (MatchedStr.startswith("mask")) { + if (MatchedStr.starts_with("mask")) { StringRef MaskType = MatchedStr.substr(sizeof("mask.") - 1); unsigned Size = MaskType.size(); if (Warn && (Size == 0 || Size > 8)) diff --git a/clang/lib/AST/RawCommentList.cpp b/clang/lib/AST/RawCommentList.cpp index c3beb23228887a8865a17268494ec46f7becb051..dffa007b6588bc05895f2789532d0f23c4586b5b 100644 --- a/clang/lib/AST/RawCommentList.cpp +++ b/clang/lib/AST/RawCommentList.cpp @@ -141,8 +141,8 @@ RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR, Kind = K.first; IsTrailingComment |= K.second; - IsAlmostTrailingComment = RawText.startswith("//<") || - RawText.startswith("/*<"); + IsAlmostTrailingComment = + RawText.starts_with("//<") || RawText.starts_with("/*<"); } else { Kind = RCK_Merged; IsTrailingComment = diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index c31fb48a2addfa3a627e8344f2d8920c970056a5..afd05881cb162107501d372bbfbaeb5a6e1d1a8a 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -811,11 +811,12 @@ std::string MSAsmStmt::generateAsmString(const ASTContext &C) const { StringRef Instruction = Pieces[I]; // For vex/vex2/vex3/evex masm style prefix, convert it to att style // since we don't support masm style prefix in backend. - if (Instruction.startswith("vex ")) + if (Instruction.starts_with("vex ")) MSAsmString += '{' + Instruction.substr(0, 3).str() + '}' + Instruction.substr(3).str(); - else if (Instruction.startswith("vex2 ") || - Instruction.startswith("vex3 ") || Instruction.startswith("evex ")) + else if (Instruction.starts_with("vex2 ") || + Instruction.starts_with("vex3 ") || + Instruction.starts_with("evex ")) MSAsmString += '{' + Instruction.substr(0, 4).str() + '}' + Instruction.substr(4).str(); else diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 435bbdeda22066e8cd42255178af66e135b639ca..8ed213ca2ce0965bf9f9c22e6a5bef8287beb4c3 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -480,11 +480,11 @@ HasNameMatcher::HasNameMatcher(std::vector N) static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) { StringRef Name = FullName; - if (!Name.endswith(Suffix)) + if (!Name.ends_with(Suffix)) return false; Name = Name.drop_back(Suffix.size()); if (!Name.empty()) { - if (!Name.endswith("::")) + if (!Name.ends_with("::")) return false; Name = Name.drop_back(2); } @@ -530,7 +530,7 @@ public: PatternSet(ArrayRef Names) { Patterns.reserve(Names.size()); for (StringRef Name : Names) - Patterns.push_back({Name, Name.startswith("::")}); + Patterns.push_back({Name, Name.starts_with("::")}); } /// Consumes the name suffix from each pattern in the set and removes the ones @@ -652,11 +652,11 @@ bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const { const StringRef FullName = OS.str(); for (const StringRef Pattern : Names) { - if (Pattern.startswith("::")) { + if (Pattern.starts_with("::")) { if (FullName == Pattern) return true; - } else if (FullName.endswith(Pattern) && - FullName.drop_back(Pattern.size()).endswith("::")) { + } else if (FullName.ends_with(Pattern) && + FullName.drop_back(Pattern.size()).ends_with("::")) { return true; } } diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp index 33a10fe838a6aa6f27fe0dc2b77c4543760a1133..6a16c2184fcfb14b6dc76ac1ac53e635b89a2111 100644 --- a/clang/lib/ASTMatchers/Dynamic/Parser.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp @@ -187,10 +187,10 @@ private: break; ++TokenLength; } - if (TokenLength == 4 && Code.startswith("true")) { + if (TokenLength == 4 && Code.starts_with("true")) { Result.Kind = TokenInfo::TK_Literal; Result.Value = true; - } else if (TokenLength == 5 && Code.startswith("false")) { + } else if (TokenLength == 5 && Code.starts_with("false")) { Result.Kind = TokenInfo::TK_Literal; Result.Value = false; } else { @@ -299,10 +299,8 @@ private: /// Consume all leading whitespace from \c Code. void consumeWhitespace() { - Code = Code.drop_while([](char c) { - // Don't trim newlines. - return StringRef(" \t\v\f\r").contains(c); - }); + // Don't trim newlines. + Code = Code.ltrim(" \t\v\f\r"); } SourceLocation currentLocation() { @@ -737,7 +735,7 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken, // Completions minus the prefix. void Parser::addCompletion(const TokenInfo &CompToken, const MatcherCompletion& Completion) { - if (StringRef(Completion.TypedText).startswith(CompToken.Text) && + if (StringRef(Completion.TypedText).starts_with(CompToken.Text) && Completion.Specificity > 0) { Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()), Completion.MatcherDecl, Completion.Specificity); diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index 13ec9b65c9f0b2ef7cd71eacceb94220a1afcb75..127e843d4ead21637f6a29c6dcd9811403df2ec6 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -726,8 +726,8 @@ Stmt *BodyFarm::getBody(const FunctionDecl *D) { FF = nullptr; break; } - } else if (Name.startswith("OSAtomicCompareAndSwap") || - Name.startswith("objc_atomicCompareAndSwap")) { + } else if (Name.starts_with("OSAtomicCompareAndSwap") || + Name.starts_with("objc_atomicCompareAndSwap")) { FF = create_OSAtomicCompareAndSwap; } else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) { FF = create_call_once; diff --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp index 59cc939b6fd15e991c4584b98c7310c379b9259f..f892980ed31386b1c6e27b085c7716b6fd856250 100644 --- a/clang/lib/Analysis/CallGraph.cpp +++ b/clang/lib/Analysis/CallGraph.cpp @@ -168,7 +168,7 @@ bool CallGraph::includeCalleeInGraph(const Decl *D) { return false; IdentifierInfo *II = FD->getIdentifier(); - if (II && II->getName().startswith("__inline")) + if (II && II->getName().starts_with("__inline")) return false; } diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp index 5b4fc24b6f0e2a557066dee417abd68d5aa3863f..04c5f6aa9c7450cdaf1b9a76c94f7dd3ddda3f59 100644 --- a/clang/lib/Analysis/CalledOnceCheck.cpp +++ b/clang/lib/Analysis/CalledOnceCheck.cpp @@ -973,7 +973,7 @@ private: /// Return true if the given name has conventional suffixes. static bool hasConventionalSuffix(llvm::StringRef Name) { return llvm::any_of(CONVENTIONAL_SUFFIXES, [Name](llvm::StringRef Suffix) { - return Name.endswith(Suffix); + return Name.ends_with(Suffix); }); } diff --git a/clang/lib/Analysis/CocoaConventions.cpp b/clang/lib/Analysis/CocoaConventions.cpp index 571d72e1a841656e681858332a336e539d4d9042..836859c2234585beed0dc70b65c6a443c9cc0428 100644 --- a/clang/lib/Analysis/CocoaConventions.cpp +++ b/clang/lib/Analysis/CocoaConventions.cpp @@ -26,10 +26,10 @@ bool cocoa::isRefType(QualType RetTy, StringRef Prefix, // Recursively walk the typedef stack, allowing typedefs of reference types. while (const TypedefType *TD = RetTy->getAs()) { StringRef TDName = TD->getDecl()->getIdentifier()->getName(); - if (TDName.startswith(Prefix) && TDName.endswith("Ref")) + if (TDName.starts_with(Prefix) && TDName.ends_with("Ref")) return true; // XPC unfortunately uses CF-style function names, but aren't CF types. - if (TDName.startswith("xpc_")) + if (TDName.starts_with("xpc_")) return false; RetTy = TD->getDecl()->getUnderlyingType(); } @@ -43,7 +43,7 @@ bool cocoa::isRefType(QualType RetTy, StringRef Prefix, return false; // Does the name start with the prefix? - return Name.startswith(Prefix); + return Name.starts_with(Prefix); } /// Returns true when the passed-in type is a CF-style reference-counted @@ -127,10 +127,9 @@ bool coreFoundation::followsCreateRule(const FunctionDecl *fn) { // Scan for *lowercase* 'reate' or 'opy', followed by no lowercase // character. StringRef suffix = functionName.substr(it - start); - if (suffix.startswith("reate")) { + if (suffix.starts_with("reate")) { it += 5; - } - else if (suffix.startswith("opy")) { + } else if (suffix.starts_with("opy")) { it += 3; } else { // Keep scanning. diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index b98037b73645225ab3cf9a35d648181ef275854f..96fe6df88dbb9f71f31581a1bd67a57cffcdb4a2 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -726,27 +726,70 @@ void Environment::setStorageLocation(const Expr &E, StorageLocation &Loc) { // so allow these as an exception. assert(E.isGLValue() || E.getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)); - setStorageLocationInternal(E, Loc); + const Expr &CanonE = ignoreCFGOmittedNodes(E); + assert(!ExprToLoc.contains(&CanonE)); + ExprToLoc[&CanonE] = &Loc; } StorageLocation *Environment::getStorageLocation(const Expr &E) const { // See comment in `setStorageLocation()`. assert(E.isGLValue() || E.getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)); - return getStorageLocationInternal(E); + auto It = ExprToLoc.find(&ignoreCFGOmittedNodes(E)); + return It == ExprToLoc.end() ? nullptr : &*It->second; +} + +// Returns whether a prvalue of record type is the one that originally +// constructs the object (i.e. it doesn't propagate it from one of its +// children). +static bool isOriginalRecordConstructor(const Expr &RecordPRValue) { + if (auto *Init = dyn_cast(&RecordPRValue)) + return !Init->isSemanticForm() || !Init->isTransparent(); + return isa(RecordPRValue) || isa(RecordPRValue) || + isa(RecordPRValue) || + // The framework currently does not propagate the objects created in + // the two branches of a `ConditionalOperator` because there is no way + // to reconcile their storage locations, which are different. We + // therefore claim that the `ConditionalOperator` is the expression + // that originally constructs the object. + // Ultimately, this will be fixed by propagating locations down from + // the result object, rather than up from the original constructor as + // we do now (see also the FIXME in the documentation for + // `getResultObjectLocation()`). + isa(RecordPRValue); } RecordStorageLocation & -Environment::getResultObjectLocation(const Expr &RecordPRValue) { +Environment::getResultObjectLocation(const Expr &RecordPRValue) const { assert(RecordPRValue.getType()->isRecordType()); assert(RecordPRValue.isPRValue()); - if (StorageLocation *ExistingLoc = getStorageLocationInternal(RecordPRValue)) - return *cast(ExistingLoc); - auto &Loc = cast( - DACtx->getStableStorageLocation(RecordPRValue)); - setStorageLocationInternal(RecordPRValue, Loc); - return Loc; + // Returns a storage location that we can use if assertions fail. + auto FallbackForAssertFailure = + [this, &RecordPRValue]() -> RecordStorageLocation & { + return cast( + DACtx->getStableStorageLocation(RecordPRValue)); + }; + + if (isOriginalRecordConstructor(RecordPRValue)) { + auto *Val = cast_or_null(getValue(RecordPRValue)); + // The builtin transfer function should have created a `RecordValue` for all + // original record constructors. + assert(Val); + if (!Val) + return FallbackForAssertFailure(); + return Val->getLoc(); + } + + // Expression nodes that propagate a record prvalue should have exactly one + // child. + llvm::SmallVector children(RecordPRValue.child_begin(), + RecordPRValue.child_end()); + assert(children.size() == 1); + if (children.empty()) + return FallbackForAssertFailure(); + + return getResultObjectLocation(*cast(children[0])); } PointerValue &Environment::getOrCreateNullPointerValue(QualType PointeeType) { @@ -760,6 +803,11 @@ void Environment::setValue(const StorageLocation &Loc, Value &Val) { } void Environment::setValue(const Expr &E, Value &Val) { + if (auto *RecordVal = dyn_cast(&Val)) { + assert(isOriginalRecordConstructor(E) || + &RecordVal->getLoc() == &getResultObjectLocation(E)); + } + assert(E.isPRValue()); ExprToVal[&E] = &Val; } @@ -799,18 +847,6 @@ Value *Environment::createValue(QualType Type) { return Val; } -void Environment::setStorageLocationInternal(const Expr &E, - StorageLocation &Loc) { - const Expr &CanonE = ignoreCFGOmittedNodes(E); - assert(!ExprToLoc.contains(&CanonE)); - ExprToLoc[&CanonE] = &Loc; -} - -StorageLocation *Environment::getStorageLocationInternal(const Expr &E) const { - auto It = ExprToLoc.find(&ignoreCFGOmittedNodes(E)); - return It == ExprToLoc.end() ? nullptr : &*It->second; -} - Value *Environment::createValueUnlessSelfReferential( QualType Type, llvm::DenseSet &Visited, int Depth, int &CreatedValuesCount) { @@ -998,7 +1034,7 @@ RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE, if (ImplicitObject == nullptr) return nullptr; if (ImplicitObject->getType()->isPointerType()) { - if (auto *Val = cast_or_null(Env.getValue(*ImplicitObject))) + if (auto *Val = Env.get(*ImplicitObject)) return &cast(Val->getPointeeLoc()); return nullptr; } @@ -1012,11 +1048,11 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, if (Base == nullptr) return nullptr; if (ME.isArrow()) { - if (auto *Val = cast_or_null(Env.getValue(*Base))) + if (auto *Val = Env.get(*Base)) return &cast(Val->getPointeeLoc()); return nullptr; } - return cast_or_null(Env.getStorageLocation(*Base)); + return Env.get(*Base); } std::vector getFieldsForInitListExpr(const RecordDecl *RD) { @@ -1041,9 +1077,10 @@ RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) { assert(Expr.getType()->isRecordType()); if (Expr.isPRValue()) { - if (auto *ExistingVal = cast_or_null(Env.getValue(Expr))) { + if (auto *ExistingVal = Env.get(Expr)) { auto &NewVal = Env.create(ExistingVal->getLoc()); Env.setValue(Expr, NewVal); + Env.setValue(NewVal.getLoc(), NewVal); return NewVal; } @@ -1052,8 +1089,7 @@ RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) { return NewVal; } - if (auto *Loc = - cast_or_null(Env.getStorageLocation(Expr))) { + if (auto *Loc = Env.get(Expr)) { auto &NewVal = Env.create(*Loc); Env.setValue(*Loc, NewVal); return NewVal; diff --git a/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp index f49087ababc44ce325c8eb08efde418da28a977f..5ac71e1d6bf64d5c8543cf01a71e44b82a606535 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp @@ -43,7 +43,7 @@ bool isCheckLikeMethod(llvm::SmallDenseSet &CheckDecls, return false; for (const CXXMethodDecl *M : ParentClass->methods()) - if (M->getDeclName().isIdentifier() && M->getName().endswith("Check")) + if (M->getDeclName().isIdentifier() && M->getName().ends_with("Check")) CheckDecls.insert(M); } diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp index 69ac2c2b82cff2407c97e30ce007a7e313f2d033..1d31b22b6d25ff305f098160340471a50a333e4d 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -226,7 +226,7 @@ auto isComparisonOperatorCall(L lhs_arg_matcher, R rhs_arg_matcher) { /// Ensures that `Expr` is mapped to a `BoolValue` and returns its formula. const Formula &forceBoolValue(Environment &Env, const Expr &Expr) { - auto *Value = cast_or_null(Env.getValue(Expr)); + auto *Value = Env.get(Expr); if (Value != nullptr) return Value->formula(); @@ -267,7 +267,7 @@ BoolValue *getHasValue(Environment &Env, RecordStorageLocation *OptionalLoc) { if (OptionalLoc == nullptr) return nullptr; StorageLocation &HasValueLoc = locForHasValue(*OptionalLoc); - auto *HasValueVal = cast_or_null(Env.getValue(HasValueLoc)); + auto *HasValueVal = Env.get(HasValueLoc); if (HasValueVal == nullptr) { HasValueVal = &Env.makeAtomicBoolValue(); Env.setValue(HasValueLoc, *HasValueVal); @@ -406,7 +406,7 @@ void transferCallReturningOptional(const CallExpr *E, if (E->isPRValue()) { Loc = &State.Env.getResultObjectLocation(*E); } else { - Loc = cast_or_null(State.Env.getStorageLocation(*E)); + Loc = State.Env.get(*E); if (Loc == nullptr) { Loc = &cast(State.Env.createStorageLocation(*E)); State.Env.setStorageLocation(*E, *Loc); @@ -449,8 +449,7 @@ BoolValue &valueOrConversionHasValue(const FunctionDecl &F, const Expr &E, // This is a constructor/assignment call for `optional` with argument of // type `optional` such that `T` is constructible from `U`. - auto *Loc = - cast_or_null(State.Env.getStorageLocation(E)); + auto *Loc = State.Env.get(E); if (auto *HasValueVal = getHasValue(State.Env, Loc)) return *HasValueVal; return State.Env.makeAtomicBoolValue(); @@ -471,8 +470,7 @@ void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal, LatticeTransferState &State) { assert(E->getNumArgs() > 0); - if (auto *Loc = cast_or_null( - State.Env.getStorageLocation(*E->getArg(0)))) { + if (auto *Loc = State.Env.get(*E->getArg(0))) { createOptionalValue(*Loc, HasValueVal, State.Env); // Assign a storage location for the whole expression. @@ -534,18 +532,15 @@ void transferSwapCall(const CXXMemberCallExpr *E, const MatchFinder::MatchResult &, LatticeTransferState &State) { assert(E->getNumArgs() == 1); - auto *OtherLoc = cast_or_null( - State.Env.getStorageLocation(*E->getArg(0))); + auto *OtherLoc = State.Env.get(*E->getArg(0)); transferSwap(getImplicitObjectLocation(*E, State.Env), OtherLoc, State.Env); } void transferStdSwapCall(const CallExpr *E, const MatchFinder::MatchResult &, LatticeTransferState &State) { assert(E->getNumArgs() == 2); - auto *Arg0Loc = cast_or_null( - State.Env.getStorageLocation(*E->getArg(0))); - auto *Arg1Loc = cast_or_null( - State.Env.getStorageLocation(*E->getArg(1))); + auto *Arg0Loc = State.Env.get(*E->getArg(0)); + auto *Arg1Loc = State.Env.get(*E->getArg(1)); transferSwap(Arg0Loc, Arg1Loc, State.Env); } @@ -585,11 +580,9 @@ void transferOptionalAndOptionalCmp(const clang::CXXOperatorCallExpr *CmpExpr, Environment &Env = State.Env; auto &A = Env.arena(); auto *CmpValue = &forceBoolValue(Env, *CmpExpr); - auto *Arg0Loc = cast_or_null( - Env.getStorageLocation(*CmpExpr->getArg(0))); + auto *Arg0Loc = Env.get(*CmpExpr->getArg(0)); if (auto *LHasVal = getHasValue(Env, Arg0Loc)) { - auto *Arg1Loc = cast_or_null( - Env.getStorageLocation(*CmpExpr->getArg(1))); + auto *Arg1Loc = Env.get(*CmpExpr->getArg(1)); if (auto *RHasVal = getHasValue(Env, Arg1Loc)) { if (CmpExpr->getOperator() == clang::OO_ExclaimEqual) CmpValue = &A.makeNot(*CmpValue); @@ -603,7 +596,7 @@ void transferOptionalAndValueCmp(const clang::CXXOperatorCallExpr *CmpExpr, const clang::Expr *E, Environment &Env) { auto &A = Env.arena(); auto *CmpValue = &forceBoolValue(Env, *CmpExpr); - auto *Loc = cast_or_null(Env.getStorageLocation(*E)); + auto *Loc = Env.get(*E); if (auto *HasVal = getHasValue(Env, Loc)) { if (CmpExpr->getOperator() == clang::OO_ExclaimEqual) CmpValue = &A.makeNot(*CmpValue); @@ -616,7 +609,7 @@ void transferOptionalAndNulloptCmp(const clang::CXXOperatorCallExpr *CmpExpr, const clang::Expr *E, Environment &Env) { auto &A = Env.arena(); auto *CmpValue = &forceBoolValue(Env, *CmpExpr); - auto *Loc = cast_or_null(Env.getStorageLocation(*E)); + auto *Loc = Env.get(*E); if (auto *HasVal = getHasValue(Env, Loc)) { if (CmpExpr->getOperator() == clang::OO_ExclaimEqual) CmpValue = &A.makeNot(*CmpValue); diff --git a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp index caaf443382b02cf4ef04eeb4bff0ec7168117a04..da4dd6dc0785159acc4e1a15a70c8a56cdf26238 100644 --- a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp @@ -66,19 +66,8 @@ void clang::dataflow::copyRecord(RecordStorageLocation &Src, } } - RecordValue *SrcVal = cast_or_null(Env.getValue(Src)); - RecordValue *DstVal = cast_or_null(Env.getValue(Dst)); - - DstVal = &Env.create(Dst); + RecordValue *DstVal = &Env.create(Dst); Env.setValue(Dst, *DstVal); - - if (SrcVal == nullptr) - return; - - for (const auto &[Name, Value] : SrcVal->properties()) { - if (Value != nullptr) - DstVal->setProperty(Name, *Value); - } } bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1, @@ -125,25 +114,5 @@ bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1, } } - llvm::StringMap Props1, Props2; - - if (RecordValue *Val1 = cast_or_null(Env1.getValue(Loc1))) - for (const auto &[Name, Value] : Val1->properties()) - Props1[Name] = Value; - if (RecordValue *Val2 = cast_or_null(Env2.getValue(Loc2))) - for (const auto &[Name, Value] : Val2->properties()) - Props2[Name] = Value; - - if (Props1.size() != Props2.size()) - return false; - - for (const auto &[Name, Value] : Props1) { - auto It = Props2.find(Name); - if (It == Props2.end()) - return false; - if (Value != It->second) - return false; - } - return true; } diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index bbf5f12359bc70e91ef4c3f2a1780a594cda0603..55093c2e2cdaf013fab818d1ed129e2bef23cd95 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -339,8 +339,7 @@ public: switch (S->getOpcode()) { case UO_Deref: { - const auto *SubExprVal = - cast_or_null(Env.getValue(*SubExpr)); + const auto *SubExprVal = Env.get(*SubExpr); if (SubExprVal == nullptr) break; @@ -467,8 +466,7 @@ public: const Expr *Arg = S->getArg(0); assert(Arg != nullptr); - auto *ArgLoc = - cast_or_null(Env.getStorageLocation(*Arg)); + auto *ArgLoc = Env.get(*Arg); if (ArgLoc == nullptr) return; @@ -489,7 +487,6 @@ public: if (S->getType()->isRecordType()) { auto &InitialVal = *cast(Env.createValue(S->getType())); Env.setValue(*S, InitialVal); - copyRecord(InitialVal.getLoc(), Env.getResultObjectLocation(*S), Env); } transferInlineCall(S, ConstructorDecl); @@ -516,14 +513,12 @@ public: RecordStorageLocation *LocSrc = nullptr; if (Arg1->isPRValue()) { - if (auto *Val = cast_or_null(Env.getValue(*Arg1))) + if (auto *Val = Env.get(*Arg1)) LocSrc = &Val->getLoc(); } else { - LocSrc = - cast_or_null(Env.getStorageLocation(*Arg1)); + LocSrc = Env.get(*Arg1); } - auto *LocDst = - cast_or_null(Env.getStorageLocation(*Arg0)); + auto *LocDst = Env.get(*Arg0); if (LocSrc == nullptr || LocDst == nullptr) return; @@ -582,6 +577,14 @@ public: Env.setValue(*S, *ArgVal); } else if (const FunctionDecl *F = S->getDirectCallee()) { transferInlineCall(S, F); + + // If this call produces a prvalue of record type, make sure that we have + // a `RecordValue` for it. This is required so that + // `Environment::getResultObjectLocation()` is able to return a location + // for this `CallExpr`. + if (S->getType()->isRecordType() && S->isPRValue()) + if (Env.getValue(*S) == nullptr) + refreshRecordValue(*S, Env); } } @@ -669,7 +672,7 @@ public: auto Init = Inits[InitIdx++]; assert(Base.getType().getCanonicalType() == Init->getType().getCanonicalType()); - auto* BaseVal = cast_or_null(Env.getValue(*Init)); + auto *BaseVal = Env.get(*Init); if (!BaseVal) BaseVal = cast(Env.createValue(Init->getType())); // Take ownership of the fields of the `RecordValue` for the base class diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 8c9360235da7c1f670507960917293dbf37966f3..faf83a8920d4ead30bf62922df79fd6c6835c000 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -130,7 +130,7 @@ private: if (Env.getValue(Cond) == nullptr) transfer(StmtToEnv, Cond, Env); - auto *Val = cast_or_null(Env.getValue(Cond)); + auto *Val = Env.get(Cond); // Value merging depends on flow conditions from different environments // being mutually exclusive -- that is, they cannot both be true in their // entirety (even if they may share some clauses). So, we need *some* value diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp index 4cbeb0c35b6f6642d9ecec63ba823fe34155454e..6f50d95b179f412342d76f19a243d3bcda7e693f 100644 --- a/clang/lib/Analysis/RetainSummaryManager.cpp +++ b/clang/lib/Analysis/RetainSummaryManager.cpp @@ -174,7 +174,7 @@ static bool isOSObjectPtr(QualType QT) { } static bool isISLObjectRef(QualType Ty) { - return StringRef(Ty.getAsString()).startswith("isl_"); + return StringRef(Ty.getAsString()).starts_with("isl_"); } static bool isOSIteratorSubclass(const Decl *D) { @@ -255,13 +255,13 @@ RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD, // TODO: Add support for the slightly common *Matching(table) idiom. // Cf. IOService::nameMatching() etc. - these function have an unusual // contract of returning at +0 or +1 depending on their last argument. - if (FName.endswith("Matching")) { + if (FName.ends_with("Matching")) { return getPersistentStopSummary(); } // All objects returned with functions *not* starting with 'get', // or iterators, are returned at +1. - if ((!FName.startswith("get") && !FName.startswith("Get")) || + if ((!FName.starts_with("get") && !FName.starts_with("Get")) || isOSIteratorSubclass(PD)) { return getOSSummaryCreateRule(FD); } else { @@ -392,9 +392,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); - } else if (FName.startswith("NSLog")) { + } else if (FName.starts_with("NSLog")) { return getDoNothingSummary(); - } else if (FName.startswith("NS") && FName.contains("Insert")) { + } else if (FName.starts_with("NS") && FName.contains("Insert")) { // Allowlist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can // be deallocated by NSMapRemove. ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking)); @@ -453,9 +453,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // Check for release functions, the only kind of functions that we care // about that don't return a pointer type. - if (FName.startswith("CG") || FName.startswith("CF")) { + if (FName.starts_with("CG") || FName.starts_with("CF")) { // Test for 'CGCF'. - FName = FName.substr(FName.startswith("CGCF") ? 4 : 2); + FName = FName.substr(FName.starts_with("CGCF") ? 4 : 2); if (isRelease(FD, FName)) return getUnarySummary(FT, DecRef); diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp index bb495216ca93ca587d776e1775ff12982a5ebbc0..44a4f1890d39e11bc70678b7cbc1cbe514b367f9 100644 --- a/clang/lib/Basic/Attributes.cpp +++ b/clang/lib/Basic/Attributes.cpp @@ -33,7 +33,7 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax, const TargetInfo &Target, const LangOptions &LangOpts) { StringRef Name = Attr->getName(); // Normalize the attribute name, __foo__ becomes foo. - if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) + if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__")) Name = Name.substr(2, Name.size() - 4); // Normalize the scope name, but only for gnu and clang attributes. @@ -103,8 +103,8 @@ static StringRef normalizeAttrName(const IdentifierInfo *Name, (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" || NormalizedScopeName == "clang")); StringRef AttrName = Name->getName(); - if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") && - AttrName.endswith("__")) + if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") && + AttrName.ends_with("__")) AttrName = AttrName.slice(2, AttrName.size() - 2); return AttrName; diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index e5667d57f8cff114c316a40526e4b116ce9e2924..6c7bd50eefb7ef618ce8df9b175aa2f13d6ade1c 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -853,5 +853,5 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) { unsigned cat = getCategoryNumberForDiag(DiagID); - return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC "); + return DiagnosticIDs::getCategoryNameFromID(cat).starts_with("ARC "); } diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 38150d1640d709d96583feab5639dbb6d0d64108..d0d8316385b452f8bc9fb35b83e542a0f7c826a1 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -604,7 +604,7 @@ LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); } static bool startsWithWord(StringRef name, StringRef word) { if (name.size() < word.size()) return false; return ((name.size() == word.size() || !isLowercase(name[word.size()])) && - name.startswith(word)); + name.starts_with(word)); } ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { @@ -628,8 +628,7 @@ ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { return OMF_performSelector; // The other method families may begin with a prefix of underscores. - while (!name.empty() && name.front() == '_') - name = name.substr(1); + name = name.ltrim('_'); if (name.empty()) return OMF_None; switch (name.front()) { @@ -742,7 +741,7 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents, std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) { StringRef Name = Sel.getNameForSlot(0); - assert(Name.startswith("set") && "invalid setter name"); + assert(Name.starts_with("set") && "invalid setter name"); return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str(); } diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 7523e509a47108c207559585d0e988371c1532ef..925217431d4d021a73154202dc50cfaf2adc5567 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -166,7 +166,8 @@ bool Module::isForBuilding(const LangOptions &LangOpts) const { // for either. if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework && CurrentModule == LangOpts.ModuleName && - !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private")) + !CurrentModule.ends_with("_Private") && + TopLevelName.ends_with("_Private")) TopLevelName = TopLevelName.drop_back(8); return TopLevelName == CurrentModule; diff --git a/clang/lib/Basic/Sarif.cpp b/clang/lib/Basic/Sarif.cpp index 3476103cc39d40890c6b5e37a2a045f91167089f..1cae7b937bc6ee2b676e68c5a8b9575b6dd7e9cf 100644 --- a/clang/lib/Basic/Sarif.cpp +++ b/clang/lib/Basic/Sarif.cpp @@ -74,7 +74,7 @@ static std::string fileNameToURI(StringRef Filename) { // Get the root name to see if it has a URI authority. StringRef Root = sys::path::root_name(Filename); - if (Root.startswith("//")) { + if (Root.starts_with("//")) { // There is an authority, so add it to the URI. Ret += Root.drop_front(2).str(); } else if (!Root.empty()) { diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 6cd5d618a4acaa59e26aa1c9aa74a0a8abac11a3..96b3ad9ba2f2731b1bd3a5443a0b6d1a5ceae6f5 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -551,26 +551,26 @@ ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const { // TODO: Support the fpmath option. It will require checking // overall feature validity for the function with the rest of the // attributes on the function. - if (Feature.startswith("fpmath=")) + if (Feature.starts_with("fpmath=")) continue; - if (Feature.startswith("branch-protection=")) { + if (Feature.starts_with("branch-protection=")) { Ret.BranchProtection = Feature.split('=').second.trim(); continue; } // While we're here iterating check for a different target cpu. - if (Feature.startswith("arch=")) { + if (Feature.starts_with("arch=")) { if (!Ret.CPU.empty()) Ret.Duplicate = "arch="; else Ret.CPU = Feature.split("=").second.trim(); - } else if (Feature.startswith("tune=")) { + } else if (Feature.starts_with("tune=")) { if (!Ret.Tune.empty()) Ret.Duplicate = "tune="; else Ret.Tune = Feature.split("=").second.trim(); - } else if (Feature.startswith("no-")) + } else if (Feature.starts_with("no-")) Ret.Features.push_back("-" + Feature.split("-").second.str()); else Ret.Features.push_back("+" + Feature.str()); diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index e3e08b571667cce2df44ebc0658b2f4f68bcd2d8..2f8395cb8932f25ae6089be9644cefd92aeb072b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -225,6 +225,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; + BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; return true; } @@ -1062,7 +1063,7 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { else // Pushing the original feature string to give a sema error later on // when they get checked. - if (Feature.startswith("no")) + if (Feature.starts_with("no")) Features.push_back("-" + Feature.drop_front(2).str()); else Features.push_back("+" + Feature.str()); @@ -1071,15 +1072,15 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { for (auto &Feature : AttrFeatures) { Feature = Feature.trim(); - if (Feature.startswith("fpmath=")) + if (Feature.starts_with("fpmath=")) continue; - if (Feature.startswith("branch-protection=")) { + if (Feature.starts_with("branch-protection=")) { Ret.BranchProtection = Feature.split('=').second.trim(); continue; } - if (Feature.startswith("arch=")) { + if (Feature.starts_with("arch=")) { if (FoundArch) Ret.Duplicate = "arch="; FoundArch = true; @@ -1095,7 +1096,7 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { Ret.Features.push_back(AI->ArchFeature.str()); // Add any extra features, after the + SplitAndAddFeatures(Split.second, Ret.Features); - } else if (Feature.startswith("cpu=")) { + } else if (Feature.starts_with("cpu=")) { if (!Ret.CPU.empty()) Ret.Duplicate = "cpu="; else { @@ -1106,14 +1107,14 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { Ret.CPU = Split.first; SplitAndAddFeatures(Split.second, Ret.Features); } - } else if (Feature.startswith("tune=")) { + } else if (Feature.starts_with("tune=")) { if (!Ret.Tune.empty()) Ret.Duplicate = "tune="; else Ret.Tune = Feature.split("=").second.trim(); - } else if (Feature.startswith("+")) { + } else if (Feature.starts_with("+")) { SplitAndAddFeatures(Feature, Ret.Features); - } else if (Feature.startswith("no-")) { + } else if (Feature.starts_with("no-")) { StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature.split("-").second); if (!FeatureName.empty()) @@ -1364,8 +1365,7 @@ bool AArch64TargetInfo::validateConstraintModifier( StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const { // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); switch (Constraint[0]) { default: diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 719fc51bfc286fb57247ea71b2c7626ce49e7e83..6f3a4908623da77926076036b44cc4c7a15b7e59 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -32,9 +32,10 @@ static const char *const DataLayoutStringR600 = static const char *const DataLayoutStringAMDGCN = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32" - "-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" + "-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:" + "32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1" - "-ni:7:8"; + "-ni:7:8:9"; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // Default @@ -279,7 +280,7 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__")); // Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___ if (isAMDGCN(getTriple())) { - assert(CanonName.startswith("gfx") && "Invalid amdgcn canonical name"); + assert(CanonName.starts_with("gfx") && "Invalid amdgcn canonical name"); Builder.defineMacro(Twine("__") + Twine(CanonName.drop_back(2).upper()) + Twine("__")); } diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index ce7e4d4639ceacbf61a78cc023da73c047d6beff..01f9e844da12a085ce3e2114775585afc9b77f00 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -419,6 +419,7 @@ bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch, BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; + BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; return true; } @@ -1229,8 +1230,7 @@ bool ARMTargetInfo::validateConstraintModifier( bool isInOut = (Constraint[0] == '+'); // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); switch (Constraint[0]) { default: diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index bc90d1b93d53f6daf14e10497d0df35d4fcfe508..3a65f53c524851b1188b9d7afb8597b2364fb9e0 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -196,7 +196,7 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, else Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper()); - if (StringRef(CPU).startswith("octeon")) + if (StringRef(CPU).starts_with("octeon")) Builder.defineMacro("__OCTEON__"); if (CPU != "mips1") { diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index 5c601812f617596526cc6d2a0e22cbc23bb5e05d..c0b5db795e2708a84a05934585271e1b6009b2fe 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -42,7 +42,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, PTXVersion = 32; for (const StringRef Feature : Opts.FeaturesAsWritten) { int PTXV; - if (!Feature.startswith("+ptx") || + if (!Feature.starts_with("+ptx") || Feature.drop_front(4).getAsInteger(10, PTXV)) continue; PTXVersion = PTXV; // TODO: should it be max(PTXVersion, PTXV)? diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 45d23022b5306b3c5e5ec41d637520dccc0cde72..6bc57a83a2d5ae6d79edc7b150ee98e60c9bcbe1 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -350,6 +350,7 @@ bool RISCVTargetInfo::hasFeature(StringRef Feature) const { .Case("riscv64", Is64Bit) .Case("32bit", !Is64Bit) .Case("64bit", Is64Bit) + .Case("experimental", HasExperimental) .Default(std::nullopt); if (Result) return *Result; @@ -382,6 +383,9 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector &Features, FastUnalignedAccess = llvm::is_contained(Features, "+fast-unaligned-access"); + if (llvm::is_contained(Features, "+experimental")) + HasExperimental = true; + return true; } @@ -412,8 +416,7 @@ static void handleFullArchString(StringRef FullArchStr, Features.push_back("__RISCV_TargetAttrNeedOverride"); auto RII = llvm::RISCVISAInfo::parseArchString( FullArchStr, /* EnableExperimentalExtension */ true); - if (!RII) { - consumeError(RII.takeError()); + if (llvm::errorToBool(RII.takeError())) { // Forward the invalid FullArchStr. Features.push_back("+" + FullArchStr.str()); } else { @@ -434,14 +437,14 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const { Feature = Feature.trim(); StringRef AttrString = Feature.split("=").second.trim(); - if (Feature.startswith("arch=")) { + if (Feature.starts_with("arch=")) { // Override last features Ret.Features.clear(); if (FoundArch) Ret.Duplicate = "arch="; FoundArch = true; - if (AttrString.startswith("+")) { + if (AttrString.starts_with("+")) { // EXTENSION like arch=+v,+zbb SmallVector Exts; AttrString.split(Exts, ","); @@ -461,7 +464,7 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const { // full-arch-string like arch=rv64gcv handleFullArchString(AttrString, Ret.Features); } - } else if (Feature.startswith("cpu=")) { + } else if (Feature.starts_with("cpu=")) { if (!Ret.CPU.empty()) Ret.Duplicate = "cpu="; @@ -475,7 +478,7 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const { handleFullArchString(MarchFromCPU, Ret.Features); } } - } else if (Feature.startswith("tune=")) { + } else if (Feature.starts_with("tune=")) { if (!Ret.Tune.empty()) Ret.Duplicate = "tune="; diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index a893cae914ce03ced8612597ce8562cae269fd00..f98c88cd45f831094073c3bd6b6c49b944322484 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -31,6 +31,7 @@ protected: private: bool FastUnalignedAccess; + bool HasExperimental = false; public: RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index b97f88647fa49f26e604ff2b99eafa5716944626..3deaa19f8d4fc4abefe0746c19d6893bb63b8830 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -1613,8 +1613,7 @@ bool X86TargetInfo::validateOutputSize(const llvm::StringMap &FeatureMap, StringRef Constraint, unsigned Size) const { // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); return validateOperandSize(FeatureMap, Constraint, Size); } diff --git a/clang/lib/Basic/Version.cpp b/clang/lib/Basic/Version.cpp index e205da7adec1d8ea569335d62bb407ae1cc3893b..4823f566bd7732d6624b647ee71511b2d6dba417 100644 --- a/clang/lib/Basic/Version.cpp +++ b/clang/lib/Basic/Version.cpp @@ -57,6 +57,14 @@ std::string getLLVMRevision() { #endif } +std::string getClangVendor() { +#ifdef CLANG_VENDOR + return CLANG_VENDOR; +#else + return ""; +#endif +} + std::string getClangFullRepositoryVersion() { std::string buf; llvm::raw_string_ostream OS(buf); @@ -92,10 +100,7 @@ std::string getClangFullVersion() { std::string getClangToolFullVersion(StringRef ToolName) { std::string buf; llvm::raw_string_ostream OS(buf); -#ifdef CLANG_VENDOR - OS << CLANG_VENDOR; -#endif - OS << ToolName << " version " CLANG_VERSION_STRING; + OS << getClangVendor() << ToolName << " version " CLANG_VERSION_STRING; std::string repo = getClangFullRepositoryVersion(); if (!repo.empty()) { @@ -110,10 +115,7 @@ std::string getClangFullCPPVersion() { // the one we report on the command line. std::string buf; llvm::raw_string_ostream OS(buf); -#ifdef CLANG_VENDOR - OS << CLANG_VENDOR; -#endif - OS << "Clang " CLANG_VERSION_STRING; + OS << getClangVendor() << "Clang " CLANG_VERSION_STRING; std::string repo = getClangFullRepositoryVersion(); if (!repo.empty()) { diff --git a/clang/lib/Basic/Warnings.cpp b/clang/lib/Basic/Warnings.cpp index cc8c138233ca1d9fcc4ef04840b87fb2efb94655..92954cab6fb040c5989677937df20b2f9bd849a7 100644 --- a/clang/lib/Basic/Warnings.cpp +++ b/clang/lib/Basic/Warnings.cpp @@ -96,11 +96,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, // Check to see if this warning starts with "no-", if so, this is a // negative form of the option. - bool isPositive = true; - if (Opt.startswith("no-")) { - isPositive = false; - Opt = Opt.substr(3); - } + bool isPositive = !Opt.consume_front("no-"); // Figure out how this option affects the warning. If -Wfoo, map the // diagnostic to a warning, if -Wno-foo, map it to ignore. @@ -133,7 +129,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, // table. It also has the "specifier" form of -Werror=foo. GCC supports // the deprecated -Werror-implicit-function-declaration which is used by // a few projects. - if (Opt.startswith("error")) { + if (Opt.starts_with("error")) { StringRef Specifier; if (Opt.size() > 5) { // Specifier must be present. if (Opt[5] != '=' && @@ -162,7 +158,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, } // -Wfatal-errors is yet another special case. - if (Opt.startswith("fatal-errors")) { + if (Opt.starts_with("fatal-errors")) { StringRef Specifier; if (Opt.size() != 12) { if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) { @@ -198,13 +194,12 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, } } - for (unsigned i = 0, e = Opts.Remarks.size(); i != e; ++i) { - StringRef Opt = Opts.Remarks[i]; + for (StringRef Opt : Opts.Remarks) { const auto Flavor = diag::Flavor::Remark; // Check to see if this warning starts with "no-", if so, this is a // negative form of the option. - bool IsPositive = !Opt.startswith("no-"); + bool IsPositive = !Opt.starts_with("no-"); if (!IsPositive) Opt = Opt.substr(3); auto Severity = IsPositive ? diag::Severity::Remark diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 77455c075cab0d9dadd52756f3a47bd62d55835d..a6142d99f3b688d1aa65fe2faeb2edcf19ae907c 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -45,6 +45,7 @@ #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" +#include "llvm/ProfileData/InstrProfCorrelator.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" @@ -102,17 +103,21 @@ static cl::opt ClSanitizeOnOptimizerEarlyEP( "sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP."), cl::init(false)); +extern cl::opt ProfileCorrelate; + // Re-link builtin bitcodes after optimization cl::opt ClRelinkBuiltinBitcodePostop( "relink-builtin-bitcode-postop", cl::Optional, cl::desc("Re-link builtin bitcodes after optimization."), cl::init(false)); -} +} // namespace llvm namespace { // Default filename used for profile generation. std::string getDefaultProfileGenName() { - return DebugInfoCorrelate ? "default_%m.proflite" : "default_%m.profraw"; + return DebugInfoCorrelate || ProfileCorrelate != InstrProfCorrelator::NONE + ? "default_%m.proflite" + : "default_%m.profraw"; } class EmitAssemblyHelper { @@ -204,7 +209,7 @@ public: void EmitAssembly(BackendAction Action, std::unique_ptr OS, BackendConsumer *BC); }; -} +} // namespace static SanitizerCoverageOptions getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts) { @@ -876,7 +881,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline( << PluginFN << toString(PassPlugin.takeError()); } } - for (auto PassCallback : CodeGenOpts.PassBuilderCallbacks) + for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks) PassCallback(PB); #define HANDLE_EXTENSION(Ext) \ get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); @@ -1063,11 +1068,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( } } if (CodeGenOpts.FatLTO) { - // Set module flags, like EnableSplitLTOUnit and UnifiedLTO, since FatLTO + // Set the EnableSplitLTOUnit and UnifiedLTO module flags, since FatLTO // uses a different action than Backend_EmitBC or Backend_EmitLL. - if (!TheModule->getModuleFlag("ThinLTO")) - TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", - uint32_t(CodeGenOpts.PrepareForThinLTO)); if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit", uint32_t(CodeGenOpts.EnableSplitLTOUnit)); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 83d0a72aac5495f55d960f066bfff6bc4a201324..f71dbf1729a1d6da7b41a73a49089e79fec37bbb 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -25,7 +25,6 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/OSLog.h" -#include "clang/AST/OperationKinds.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" @@ -232,19 +231,19 @@ static Value *MakeBinaryAtomicValue( static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) { Value *Val = CGF.EmitScalarExpr(E->getArg(0)); - Value *Address = CGF.EmitScalarExpr(E->getArg(1)); + Address Addr = CGF.EmitPointerWithAlignment(E->getArg(1)); Val = CGF.EmitToMemory(Val, E->getArg(0)->getType()); - LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getArg(0)->getType()); + LValue LV = CGF.MakeAddrLValue(Addr, E->getArg(0)->getType()); LV.setNontemporal(true); CGF.EmitStoreOfScalar(Val, LV, false); return nullptr; } static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { - Value *Address = CGF.EmitScalarExpr(E->getArg(0)); + Address Addr = CGF.EmitPointerWithAlignment(E->getArg(0)); - LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType()); + LValue LV = CGF.MakeAddrLValue(Addr, E->getType()); LV.setNontemporal(true); return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); } @@ -819,165 +818,6 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); } -llvm::Value * -CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, - llvm::IntegerType *ResType) { - // The code generated here calculates the size of a struct with a flexible - // array member that uses the counted_by attribute. There are two instances - // we handle: - // - // struct s { - // unsigned long flags; - // int count; - // int array[] __attribute__((counted_by(count))); - // } - // - // 1) bdos of the flexible array itself: - // - // __builtin_dynamic_object_size(p->array, 1) == - // p->count * sizeof(*p->array) - // - // 2) bdos of a pointer into the flexible array: - // - // __builtin_dynamic_object_size(&p->array[42], 1) == - // (p->count - 42) * sizeof(*p->array) - // - // 2) bdos of the whole struct, including the flexible array: - // - // __builtin_dynamic_object_size(p, 1) == - // max(sizeof(struct s), - // offsetof(struct s, array) + p->count * sizeof(*p->array)) - // - ASTContext &Ctx = getContext(); - const Expr *Base = E->IgnoreParenImpCasts(); - const Expr *Idx = nullptr; - - if (const auto *UO = dyn_cast(Base); - UO && UO->getOpcode() == UO_AddrOf) { - Expr *SubExpr = UO->getSubExpr()->IgnoreParenImpCasts(); - if (const auto *ASE = dyn_cast(SubExpr)) { - Base = ASE->getBase()->IgnoreParenImpCasts(); - Idx = ASE->getIdx()->IgnoreParenImpCasts(); - - if (const auto *IL = dyn_cast(Idx)) { - int64_t Val = IL->getValue().getSExtValue(); - if (Val < 0) - // __bdos returns 0 for negative indexes into an array in a struct. - return getDefaultBuiltinObjectSizeResult(Type, ResType); - - if (Val == 0) - // The index is 0, so we don't need to take it into account. - Idx = nullptr; - } - } else { - // Potential pointer to another element in the struct. - Base = SubExpr; - } - } - - // Get the flexible array member Decl. - const ValueDecl *FAMDecl = nullptr; - if (const auto *ME = dyn_cast(Base)) { - // Check if \p Base is referencing the FAM itself. - if (const ValueDecl *MD = ME->getMemberDecl()) { - const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = - getLangOpts().getStrictFlexArraysLevel(); - if (!Decl::isFlexibleArrayMemberLike( - Ctx, MD, MD->getType(), StrictFlexArraysLevel, - /*IgnoreTemplateOrMacroSubstitution=*/true)) - return nullptr; - - FAMDecl = MD; - } - } else if (const auto *DRE = dyn_cast(Base)) { - // Check if we're pointing to the whole struct. - QualType Ty = DRE->getDecl()->getType(); - if (Ty->isPointerType()) - Ty = Ty->getPointeeType(); - - if (const auto *RD = Ty->getAsRecordDecl()) - // Don't use the outer lexical record because the FAM might be in a - // different RecordDecl. - FAMDecl = FindFlexibleArrayMemberField(Ctx, RD); - } - - if (!FAMDecl || !FAMDecl->hasAttr()) - // No flexible array member found or it doesn't have the "counted_by" - // attribute. - return nullptr; - - const ValueDecl *CountedByFD = FindCountedByField(Base); - if (!CountedByFD) - // Can't find the field referenced by the "counted_by" attribute. - return nullptr; - - // Build a load of the counted_by field. - bool IsSigned = CountedByFD->getType()->isSignedIntegerType(); - const Expr *CountedByExpr = BuildCountedByFieldExpr(Base, CountedByFD); - Value *CountedByInst = EmitAnyExprToTemp(CountedByExpr).getScalarVal(); - llvm::Type *CountedByTy = CountedByInst->getType(); - - // Build a load of the index and subtract it from the count. - Value *IdxInst = nullptr; - if (Idx) { - bool IdxSigned = Idx->getType()->isSignedIntegerType(); - IdxInst = EmitAnyExprToTemp(Idx).getScalarVal(); - IdxInst = IdxSigned ? Builder.CreateSExtOrTrunc(IdxInst, CountedByTy) - : Builder.CreateZExtOrTrunc(IdxInst, CountedByTy); - - // We go ahead with the calculation here. If the index turns out to be - // negative, we'll catch it at the end. - CountedByInst = - Builder.CreateSub(CountedByInst, IdxInst, "", !IsSigned, IsSigned); - } - - // Calculate how large the flexible array member is in bytes. - const ArrayType *ArrayTy = Ctx.getAsArrayType(FAMDecl->getType()); - CharUnits Size = Ctx.getTypeSizeInChars(ArrayTy->getElementType()); - llvm::Constant *ElemSize = - llvm::ConstantInt::get(CountedByTy, Size.getQuantity(), IsSigned); - Value *FAMSize = - Builder.CreateMul(CountedByInst, ElemSize, "", !IsSigned, IsSigned); - FAMSize = IsSigned ? Builder.CreateSExtOrTrunc(FAMSize, ResType) - : Builder.CreateZExtOrTrunc(FAMSize, ResType); - Value *Res = FAMSize; - - if (const auto *DRE = dyn_cast(Base)) { - // The whole struct is specificed in the __bdos. - const RecordDecl *OuterRD = - CountedByFD->getDeclContext()->getOuterLexicalRecordContext(); - const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(OuterRD); - - // Get the offset of the FAM. - CharUnits Offset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FAMDecl)); - llvm::Constant *FAMOffset = - ConstantInt::get(ResType, Offset.getQuantity(), IsSigned); - Value *OffsetAndFAMSize = - Builder.CreateAdd(FAMOffset, Res, "", !IsSigned, IsSigned); - - // Get the full size of the struct. - llvm::Constant *SizeofStruct = - ConstantInt::get(ResType, Layout.getSize().getQuantity(), IsSigned); - - // max(sizeof(struct s), - // offsetof(struct s, array) + p->count * sizeof(*p->array)) - Res = IsSigned - ? Builder.CreateBinaryIntrinsic(llvm::Intrinsic::smax, - OffsetAndFAMSize, SizeofStruct) - : Builder.CreateBinaryIntrinsic(llvm::Intrinsic::umax, - OffsetAndFAMSize, SizeofStruct); - } - - // A negative \p IdxInst or \p CountedByInst means that the index lands - // outside of the flexible array member. If that's the case, we want to - // return 0. - Value *Cmp = Builder.CreateIsNotNeg(CountedByInst); - if (IdxInst) - Cmp = Builder.CreateAnd(Builder.CreateIsNotNeg(IdxInst), Cmp); - - return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, IsSigned)); -} - /// Returns a Value corresponding to the size of the given expression. /// This Value may be either of the following: /// - A llvm::Argument (if E is a param with the pass_object_size attribute on @@ -1010,13 +850,6 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, } } - if (IsDynamic) { - // Emit special code for a flexible array member with the "counted_by" - // attribute. - if (Value *V = emitFlexibleArrayMemberSize(E, Type, ResType)) - return V; - } - // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't // evaluate E for side-effects. In either case, we shouldn't lower to // @llvm.objectsize. @@ -3214,7 +3047,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *AlignmentValue = EmitScalarExpr(E->getArg(1)); ConstantInt *AlignmentCI = cast(AlignmentValue); if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment)) - AlignmentCI = ConstantInt::get(AlignmentCI->getType(), + AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(), llvm::Value::MaximumAlignment); emitAlignmentAssumption(PtrValue, Ptr, @@ -3410,9 +3243,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, { Src0->getType(), Src1->getType() }); return RValue::get(Builder.CreateCall(F, { Src0, Src1 })); } + case Builtin::BI__builtin_frexpl: { + // Linux PPC will not be adding additional PPCDoubleDouble support. + // WIP to switch default to IEEE long double. Will emit libcall for + // frexpl instead of legalizing this type in the BE. + if (&getTarget().getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble()) + break; + LLVM_FALLTHROUGH; + } case Builtin::BI__builtin_frexp: case Builtin::BI__builtin_frexpf: - case Builtin::BI__builtin_frexpl: case Builtin::BI__builtin_frexpf128: case Builtin::BI__builtin_frexpf16: return RValue::get(emitFrexpBuiltin(*this, E, Intrinsic::frexp)); @@ -9985,6 +9825,10 @@ CodeGenFunction::getSVEOverloadTypes(const SVETypeFlags &TypeFlags, if (TypeFlags.isOverloadCvt()) return {Ops[0]->getType(), Ops.back()->getType()}; + if (TypeFlags.isReductionQV() && !ResultType->isScalableTy() && + ResultType->isVectorTy()) + return {ResultType, Ops[1]->getType()}; + assert(TypeFlags.isOverloadDefault() && "Unexpected value for overloads"); return {DefaultType}; } @@ -10474,6 +10318,30 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, return nullptr; } +static void swapCommutativeSMEOperands(unsigned BuiltinID, + SmallVectorImpl &Ops) { + unsigned MultiVec; + switch (BuiltinID) { + default: + return; + case SME::BI__builtin_sme_svsumla_za32_s8_vg4x1: + MultiVec = 1; + break; + case SME::BI__builtin_sme_svsumla_za32_s8_vg4x2: + case SME::BI__builtin_sme_svsudot_za32_s8_vg1x2: + MultiVec = 2; + break; + case SME::BI__builtin_sme_svsudot_za32_s8_vg1x4: + case SME::BI__builtin_sme_svsumla_za32_s8_vg4x4: + MultiVec = 4; + break; + } + + if (MultiVec > 0) + for (unsigned I = 0; I < MultiVec; ++I) + std::swap(Ops[I + 1], Ops[I + 1 + MultiVec]); +} + Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { auto *Builtin = findARMVectorIntrinsicInMap(AArch64SMEIntrinsicMap, BuiltinID, @@ -10496,6 +10364,9 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, BuiltinID == SME::BI__builtin_sme_svstr_za) return EmitSMELdrStr(TypeFlags, Ops, Builtin->LLVMIntrinsic); + // Handle builtins which require their multi-vector operands to be swapped + swapCommutativeSMEOperands(BuiltinID, Ops); + // Should not happen! if (Builtin->LLVMIntrinsic == 0) return nullptr; @@ -10559,6 +10430,26 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); } + if (BuiltinID == clang::AArch64::BI__builtin_arm_get_sme_state) { + // Create call to __arm_sme_state and store the results to the two pointers. + CallInst *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction( + llvm::FunctionType::get(StructType::get(CGM.Int64Ty, CGM.Int64Ty), {}, + false), + "__arm_sme_state")); + auto Attrs = + AttributeList() + .addFnAttribute(getLLVMContext(), "aarch64_pstate_sm_compatible") + .addFnAttribute(getLLVMContext(), "aarch64_pstate_za_preserved"); + CI->setAttributes(Attrs); + CI->setCallingConv( + llvm::CallingConv:: + AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2); + Builder.CreateStore(Builder.CreateExtractValue(CI, 0), + EmitPointerWithAlignment(E->getArg(0))); + return Builder.CreateStore(Builder.CreateExtractValue(CI, 1), + EmitPointerWithAlignment(E->getArg(1))); + } + if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit) { assert((getContext().getTypeSize(E->getType()) == 32) && "rbit of unusual size!"); @@ -17023,7 +16914,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Value *Op1 = EmitScalarExpr(E->getArg(1)); ConstantInt *AlignmentCI = cast(Op0); if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment)) - AlignmentCI = ConstantInt::get(AlignmentCI->getType(), + AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(), llvm::Value::MaximumAlignment); emitAlignmentAssumption(Op1, E->getArg(1), @@ -17261,7 +17152,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Op0, llvm::FixedVectorType::get(ConvertType(E->getType()), 2)); if (getTarget().isLittleEndian()) - Index = ConstantInt::get(Index->getType(), 1 - Index->getZExtValue()); + Index = + ConstantInt::get(Index->getIntegerType(), 1 - Index->getZExtValue()); return Builder.CreateExtractElement(Unpacked, Index); } diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 520b0c4f117673f76b93279d7bdaa0f26a21784f..353370f1d761b92c376bd0bc3582a3015d4c101e 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -39,7 +39,7 @@ class CGNVCUDARuntime : public CGCUDARuntime { private: llvm::IntegerType *IntTy, *SizeTy; llvm::Type *VoidTy; - llvm::PointerType *CharPtrTy, *VoidPtrTy, *VoidPtrPtrTy; + llvm::PointerType *PtrTy; /// Convenience reference to LLVM Context llvm::LLVMContext &Context; @@ -232,15 +232,12 @@ CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) VoidTy = CGM.VoidTy; Zeros[0] = llvm::ConstantInt::get(SizeTy, 0); Zeros[1] = Zeros[0]; - - CharPtrTy = CGM.UnqualPtrTy; - VoidPtrTy = CGM.UnqualPtrTy; - VoidPtrPtrTy = CGM.UnqualPtrTy; + PtrTy = CGM.UnqualPtrTy; } llvm::FunctionCallee CGNVCUDARuntime::getSetupArgumentFn() const { // cudaError_t cudaSetupArgument(void *, size_t, size_t) - llvm::Type *Params[] = {VoidPtrTy, SizeTy, SizeTy}; + llvm::Type *Params[] = {PtrTy, SizeTy, SizeTy}; return CGM.CreateRuntimeFunction( llvm::FunctionType::get(IntTy, Params, false), addPrefixToName("SetupArgument")); @@ -250,24 +247,24 @@ llvm::FunctionCallee CGNVCUDARuntime::getLaunchFn() const { if (CGM.getLangOpts().HIP) { // hipError_t hipLaunchByPtr(char *); return CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IntTy, CharPtrTy, false), "hipLaunchByPtr"); + llvm::FunctionType::get(IntTy, PtrTy, false), "hipLaunchByPtr"); } // cudaError_t cudaLaunch(char *); - return CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IntTy, CharPtrTy, false), "cudaLaunch"); + return CGM.CreateRuntimeFunction(llvm::FunctionType::get(IntTy, PtrTy, false), + "cudaLaunch"); } llvm::FunctionType *CGNVCUDARuntime::getRegisterGlobalsFnTy() const { - return llvm::FunctionType::get(VoidTy, VoidPtrPtrTy, false); + return llvm::FunctionType::get(VoidTy, PtrTy, false); } llvm::FunctionType *CGNVCUDARuntime::getCallbackFnTy() const { - return llvm::FunctionType::get(VoidTy, VoidPtrTy, false); + return llvm::FunctionType::get(VoidTy, PtrTy, false); } llvm::FunctionType *CGNVCUDARuntime::getRegisterLinkedBinaryFnTy() const { - llvm::Type *Params[] = {llvm::PointerType::getUnqual(Context), VoidPtrTy, - VoidPtrTy, llvm::PointerType::getUnqual(Context)}; + llvm::Type *Params[] = {llvm::PointerType::getUnqual(Context), PtrTy, PtrTy, + llvm::PointerType::getUnqual(Context)}; return llvm::FunctionType::get(VoidTy, Params, false); } @@ -330,15 +327,15 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, // args, allocate a single pointer so we still have a valid pointer to the // argument array that we can pass to runtime, even if it will be unused. Address KernelArgs = CGF.CreateTempAlloca( - VoidPtrTy, CharUnits::fromQuantity(16), "kernel_args", + PtrTy, CharUnits::fromQuantity(16), "kernel_args", llvm::ConstantInt::get(SizeTy, std::max(1, Args.size()))); // Store pointers to the arguments in a locally allocated launch_args. for (unsigned i = 0; i < Args.size(); ++i) { llvm::Value* VarPtr = CGF.GetAddrOfLocalVar(Args[i]).getPointer(); - llvm::Value *VoidVarPtr = CGF.Builder.CreatePointerCast(VarPtr, VoidPtrTy); + llvm::Value *VoidVarPtr = CGF.Builder.CreatePointerCast(VarPtr, PtrTy); CGF.Builder.CreateDefaultAlignedStore( VoidVarPtr, - CGF.Builder.CreateConstGEP1_32(VoidPtrTy, KernelArgs.getPointer(), i)); + CGF.Builder.CreateConstGEP1_32(PtrTy, KernelArgs.getPointer(), i)); } llvm::BasicBlock *EndBlock = CGF.createBasicBlock("setup.end"); @@ -386,8 +383,7 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, CGF.CreateMemTemp(Dim3Ty, CharUnits::fromQuantity(8), "block_dim"); Address ShmemSize = CGF.CreateTempAlloca(SizeTy, CGM.getSizeAlign(), "shmem_size"); - Address Stream = - CGF.CreateTempAlloca(VoidPtrTy, CGM.getPointerAlign(), "stream"); + Address Stream = CGF.CreateTempAlloca(PtrTy, CGM.getPointerAlign(), "stream"); llvm::FunctionCallee cudaPopConfigFn = CGM.CreateRuntimeFunction( llvm::FunctionType::get(IntTy, {/*gridDim=*/GridDim.getType(), @@ -402,8 +398,8 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, ShmemSize.getPointer(), Stream.getPointer()}); // Emit the call to cudaLaunch - llvm::Value *Kernel = CGF.Builder.CreatePointerCast( - KernelHandles[CGF.CurFn->getName()], VoidPtrTy); + llvm::Value *Kernel = + CGF.Builder.CreatePointerCast(KernelHandles[CGF.CurFn->getName()], PtrTy); CallArgList LaunchKernelArgs; LaunchKernelArgs.add(RValue::get(Kernel), cudaLaunchKernelFD->getParamDecl(0)->getType()); @@ -443,7 +439,7 @@ void CGNVCUDARuntime::emitDeviceStubBodyLegacy(CodeGenFunction &CGF, Offset = Offset.alignTo(TInfo.Align); llvm::Value *Args[] = { CGF.Builder.CreatePointerCast(CGF.GetAddrOfLocalVar(A).getPointer(), - VoidPtrTy), + PtrTy), llvm::ConstantInt::get(SizeTy, TInfo.Width.getQuantity()), llvm::ConstantInt::get(SizeTy, Offset.getQuantity()), }; @@ -458,8 +454,8 @@ void CGNVCUDARuntime::emitDeviceStubBodyLegacy(CodeGenFunction &CGF, // Emit the call to cudaLaunch llvm::FunctionCallee cudaLaunchFn = getLaunchFn(); - llvm::Value *Arg = CGF.Builder.CreatePointerCast( - KernelHandles[CGF.CurFn->getName()], CharPtrTy); + llvm::Value *Arg = + CGF.Builder.CreatePointerCast(KernelHandles[CGF.CurFn->getName()], PtrTy); CGF.EmitRuntimeCallOrInvoke(cudaLaunchFn, Arg); CGF.EmitBranch(EndBlock); @@ -537,11 +533,8 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() { // void __cudaRegisterFunction(void **, const char *, char *, const char *, // int, uint3*, uint3*, dim3*, dim3*, int*) llvm::Type *RegisterFuncParams[] = { - VoidPtrPtrTy, CharPtrTy, - CharPtrTy, CharPtrTy, - IntTy, VoidPtrTy, - VoidPtrTy, VoidPtrTy, - VoidPtrTy, llvm::PointerType::getUnqual(Context)}; + PtrTy, PtrTy, PtrTy, PtrTy, IntTy, + PtrTy, PtrTy, PtrTy, PtrTy, llvm::PointerType::getUnqual(Context)}; llvm::FunctionCallee RegisterFunc = CGM.CreateRuntimeFunction( llvm::FunctionType::get(IntTy, RegisterFuncParams, false), addUnderscoredPrefixToName("RegisterFunction")); @@ -553,7 +546,7 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() { for (auto &&I : EmittedKernels) { llvm::Constant *KernelName = makeConstantString(getDeviceSideName(cast(I.D))); - llvm::Constant *NullPtr = llvm::ConstantPointerNull::get(VoidPtrTy); + llvm::Constant *NullPtr = llvm::ConstantPointerNull::get(PtrTy); llvm::Value *Args[] = { &GpuBinaryHandlePtr, KernelHandles[I.Kernel->getName()], @@ -576,16 +569,15 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() { // void __cudaRegisterVar(void **, char *, char *, const char *, // int, int, int, int) - llvm::Type *RegisterVarParams[] = {VoidPtrPtrTy, CharPtrTy, CharPtrTy, - CharPtrTy, IntTy, VarSizeTy, - IntTy, IntTy}; + llvm::Type *RegisterVarParams[] = {PtrTy, PtrTy, PtrTy, PtrTy, + IntTy, VarSizeTy, IntTy, IntTy}; llvm::FunctionCallee RegisterVar = CGM.CreateRuntimeFunction( llvm::FunctionType::get(VoidTy, RegisterVarParams, false), addUnderscoredPrefixToName("RegisterVar")); // void __hipRegisterManagedVar(void **, char *, char *, const char *, // size_t, unsigned) - llvm::Type *RegisterManagedVarParams[] = {VoidPtrPtrTy, CharPtrTy, CharPtrTy, - CharPtrTy, VarSizeTy, IntTy}; + llvm::Type *RegisterManagedVarParams[] = {PtrTy, PtrTy, PtrTy, + PtrTy, VarSizeTy, IntTy}; llvm::FunctionCallee RegisterManagedVar = CGM.CreateRuntimeFunction( llvm::FunctionType::get(VoidTy, RegisterManagedVarParams, false), addUnderscoredPrefixToName("RegisterManagedVar")); @@ -593,16 +585,13 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() { // const void **, const char *, int, int); llvm::FunctionCallee RegisterSurf = CGM.CreateRuntimeFunction( llvm::FunctionType::get( - VoidTy, {VoidPtrPtrTy, VoidPtrTy, CharPtrTy, CharPtrTy, IntTy, IntTy}, - false), + VoidTy, {PtrTy, PtrTy, PtrTy, PtrTy, IntTy, IntTy}, false), addUnderscoredPrefixToName("RegisterSurface")); // void __cudaRegisterTexture(void **, const struct textureReference *, // const void **, const char *, int, int, int) llvm::FunctionCallee RegisterTex = CGM.CreateRuntimeFunction( llvm::FunctionType::get( - VoidTy, - {VoidPtrPtrTy, VoidPtrTy, CharPtrTy, CharPtrTy, IntTy, IntTy, IntTy}, - false), + VoidTy, {PtrTy, PtrTy, PtrTy, PtrTy, IntTy, IntTy, IntTy}, false), addUnderscoredPrefixToName("RegisterTexture")); for (auto &&Info : DeviceVars) { llvm::GlobalVariable *Var = Info.Var; @@ -713,11 +702,11 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { // void ** __{cuda|hip}RegisterFatBinary(void *); llvm::FunctionCallee RegisterFatbinFunc = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(VoidPtrPtrTy, VoidPtrTy, false), + llvm::FunctionType::get(PtrTy, PtrTy, false), addUnderscoredPrefixToName("RegisterFatBinary")); // struct { int magic, int version, void * gpu_binary, void * dont_care }; llvm::StructType *FatbinWrapperTy = - llvm::StructType::get(IntTy, IntTy, VoidPtrTy, VoidPtrTy); + llvm::StructType::get(IntTy, IntTy, PtrTy, PtrTy); // Register GPU binary with the CUDA runtime, store returned handle in a // global variable and save a reference in GpuBinaryHandle to be cleaned up @@ -813,7 +802,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { // Data. Values.add(FatBinStr); // Unused in fatbin v1. - Values.add(llvm::ConstantPointerNull::get(VoidPtrTy)); + Values.add(llvm::ConstantPointerNull::get(PtrTy)); llvm::GlobalVariable *FatbinWrapper = Values.finishAndCreateGlobal( addUnderscoredPrefixToName("_fatbin_wrapper"), CGM.getPointerAlign(), /*constant*/ true); @@ -836,9 +825,8 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { // The name, size, and initialization pattern of this variable is part // of HIP ABI. GpuBinaryHandle = new llvm::GlobalVariable( - TheModule, VoidPtrPtrTy, /*isConstant=*/false, - Linkage, - /*Initializer=*/llvm::ConstantPointerNull::get(VoidPtrPtrTy), + TheModule, PtrTy, /*isConstant=*/false, Linkage, + /*Initializer=*/llvm::ConstantPointerNull::get(PtrTy), "__hip_gpubin_handle"); if (Linkage == llvm::GlobalValue::LinkOnceAnyLinkage) GpuBinaryHandle->setComdat( @@ -848,7 +836,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { if (Linkage != llvm::GlobalValue::InternalLinkage) GpuBinaryHandle->setVisibility(llvm::GlobalValue::HiddenVisibility); Address GpuBinaryAddr( - GpuBinaryHandle, VoidPtrPtrTy, + GpuBinaryHandle, PtrTy, CharUnits::fromQuantity(GpuBinaryHandle->getAlignment())); { auto *HandleValue = CtorBuilder.CreateLoad(GpuBinaryAddr); @@ -880,8 +868,8 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { llvm::CallInst *RegisterFatbinCall = CtorBuilder.CreateCall(RegisterFatbinFunc, FatbinWrapper); GpuBinaryHandle = new llvm::GlobalVariable( - TheModule, VoidPtrPtrTy, false, llvm::GlobalValue::InternalLinkage, - llvm::ConstantPointerNull::get(VoidPtrPtrTy), "__cuda_gpubin_handle"); + TheModule, PtrTy, false, llvm::GlobalValue::InternalLinkage, + llvm::ConstantPointerNull::get(PtrTy), "__cuda_gpubin_handle"); GpuBinaryHandle->setAlignment(CGM.getPointerAlign().getAsAlign()); CtorBuilder.CreateAlignedStore(RegisterFatbinCall, GpuBinaryHandle, CGM.getPointerAlign()); @@ -895,7 +883,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { CudaFeature::CUDA_USES_FATBIN_REGISTER_END)) { // void __cudaRegisterFatBinaryEnd(void **); llvm::FunctionCallee RegisterFatbinEndFunc = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(VoidTy, VoidPtrPtrTy, false), + llvm::FunctionType::get(VoidTy, PtrTy, false), "__cudaRegisterFatBinaryEnd"); CtorBuilder.CreateCall(RegisterFatbinEndFunc, RegisterFatbinCall); } @@ -967,7 +955,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleDtorFunction() { // void __cudaUnregisterFatBinary(void ** handle); llvm::FunctionCallee UnregisterFatbinFunc = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(VoidTy, VoidPtrPtrTy, false), + llvm::FunctionType::get(VoidTy, PtrTy, false), addUnderscoredPrefixToName("UnregisterFatBinary")); llvm::Function *ModuleDtorFunc = llvm::Function::Create( diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a24aeea7ae32bfc9b58a8fe5c2b024fb3d46f2e7..51a43b5f85b3cc40cb135ab04593f181f1e29369 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5609,7 +5609,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, EmitBlock(Cont); } if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() && - CI->getCalledFunction()->getName().startswith("_Z4sqrt")) { + CI->getCalledFunction()->getName().starts_with("_Z4sqrt")) { SetSqrtFPAccuracy(CI); } if (callOrInvoke) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 37d7a6755d3908c051440edb25f38a4f1c02d216..236d53bee4e8f1888782c0bd8ae46b2122b1ee75 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -637,7 +637,8 @@ void CGDebugInfo::CreateCompileUnit() { Sysroot = CGM.getHeaderSearchOpts().Sysroot; auto B = llvm::sys::path::rbegin(Sysroot); auto E = llvm::sys::path::rend(Sysroot); - auto It = std::find_if(B, E, [](auto SDK) { return SDK.endswith(".sdk"); }); + auto It = + std::find_if(B, E, [](auto SDK) { return SDK.ends_with(".sdk"); }); if (It != E) SDK = *It; } @@ -2885,7 +2886,7 @@ llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod, // clang::Module object, but it won't actually be built or imported; it will // be textual. if (CreateSkeletonCU && IsRootModule && Mod.getASTFile().empty() && M) - assert(StringRef(M->Name).startswith(CGM.getLangOpts().ModuleName) && + assert(StringRef(M->Name).starts_with(CGM.getLangOpts().ModuleName) && "clang module without ASTFile must be specified by -fmodule-name"); // Return a StringRef to the remapped Path. @@ -4249,7 +4250,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc, Flags |= llvm::DINode::FlagPrototyped; } - if (Name.startswith("\01")) + if (Name.starts_with("\01")) Name = Name.substr(1); assert((!D || !isa(D) || diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index bae8babb8efe4a8cfdbcad74c0877e3f0064ad15..0d507da5c1ba92f78ac5df4f0840c9e7edf605ac 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -277,7 +277,7 @@ static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) { if (llvm::GlobalVariable *GV = dyn_cast(Val)) // ObjC EH selector entries are always global variables with // names starting like this. - if (GV->getName().startswith("OBJC_EHTYPE")) + if (GV->getName().starts_with("OBJC_EHTYPE")) return false; } else { // Check if any of the filter values have the ObjC prefix. @@ -288,7 +288,7 @@ static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) { cast((*II)->stripPointerCasts())) // ObjC EH selector entries are always global variables with // names starting like this. - if (GV->getName().startswith("OBJC_EHTYPE")) + if (GV->getName().starts_with("OBJC_EHTYPE")) return false; } } @@ -1917,7 +1917,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, const VarDecl *D = cast(I.first); if (isa(D) && D->getType() == getContext().VoidPtrTy) { - assert(D->getName().startswith("frame_pointer")); + assert(D->getName().starts_with("frame_pointer")); FramePtrAddrAlloca = cast(I.second.getPointer()); break; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 69cf7f76be9a7091742e3498c1a904ec838eafe5..3f277725d9e7fc2a5e548124ce48501045bf3b95 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -30,7 +30,6 @@ #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" @@ -431,7 +430,7 @@ static Address createReferenceTemporary(CodeGenFunction &CGF, /// Helper method to check if the underlying ABI is AAPCS static bool isAAPCS(const TargetInfo &TargetInfo) { - return TargetInfo.getABI().startswith("aapcs"); + return TargetInfo.getABI().starts_with("aapcs"); } LValue CodeGenFunction:: @@ -926,27 +925,16 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF, if (CE->getCastKind() == CK_ArrayToPointerDecay && !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(), StrictFlexArraysLevel)) { - CodeGenFunction::SanitizerScope SanScope(&CGF); - IndexedType = CE->getSubExpr()->getType(); const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe(); if (const auto *CAT = dyn_cast(AT)) return CGF.Builder.getInt(CAT->getSize()); - - if (const auto *VAT = dyn_cast(AT)) + else if (const auto *VAT = dyn_cast(AT)) return CGF.getVLASize(VAT).NumElts; // Ignore pass_object_size here. It's not applicable on decayed pointers. } - - if (const ValueDecl *VD = CGF.FindCountedByField(Base)) { - IndexedType = Base->getType(); - const Expr *E = CGF.BuildCountedByFieldExpr(Base, VD); - return CGF.EmitAnyExprToTemp(E).getScalarVal(); - } } - CodeGenFunction::SanitizerScope SanScope(&CGF); - QualType EltTy{Base->getType()->getPointeeOrArrayElementType(), 0}; if (llvm::Value *POS = CGF.LoadPassedObjectSize(Base, EltTy)) { IndexedType = Base->getType(); @@ -956,122 +944,13 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF, return nullptr; } -const Expr * -CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base, - const ValueDecl *CountedByVD) { - // Find the outer struct expr (i.e. p in p->a.b.c.d). - Expr *CountedByExpr = const_cast(Base)->IgnoreParenImpCasts(); - - // Work our way up the expression until we reach the DeclRefExpr. - while (!isa(CountedByExpr)) - if (const auto *ME = dyn_cast(CountedByExpr)) - CountedByExpr = ME->getBase()->IgnoreParenImpCasts(); - - // Add back an implicit cast to create the required pr-value. - CountedByExpr = ImplicitCastExpr::Create( - getContext(), CountedByExpr->getType(), CK_LValueToRValue, CountedByExpr, - nullptr, VK_PRValue, FPOptionsOverride()); - - if (const auto *IFD = dyn_cast(CountedByVD)) { - // The counted_by field is inside an anonymous struct / union. The - // IndirectFieldDecl has the correct order of FieldDecls to build this - // easily. (Yay!) - for (NamedDecl *ND : IFD->chain()) { - auto *VD = cast(ND); - CountedByExpr = - MemberExpr::CreateImplicit(getContext(), CountedByExpr, - CountedByExpr->getType()->isPointerType(), - VD, VD->getType(), VK_LValue, OK_Ordinary); - } - } else { - CountedByExpr = MemberExpr::CreateImplicit( - getContext(), const_cast(CountedByExpr), - CountedByExpr->getType()->isPointerType(), - const_cast(CountedByVD), CountedByVD->getType(), VK_LValue, - OK_Ordinary); - } - - return CountedByExpr; -} - -const ValueDecl * -CodeGenFunction::FindFlexibleArrayMemberField(ASTContext &Ctx, - const RecordDecl *RD) { - const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = - getLangOpts().getStrictFlexArraysLevel(); - - for (const Decl *D : RD->decls()) { - if (const auto *VD = dyn_cast(D); - VD && Decl::isFlexibleArrayMemberLike( - Ctx, VD, VD->getType(), StrictFlexArraysLevel, - /*IgnoreTemplateOrMacroSubstitution=*/true)) - return VD; - - if (const auto *Record = dyn_cast(D)) - if (const ValueDecl *VD = FindFlexibleArrayMemberField(Ctx, Record)) - return VD; - } - - return nullptr; -} - -const ValueDecl *CodeGenFunction::FindCountedByField(const Expr *Base) { - ASTContext &Ctx = getContext(); - const RecordDecl *OuterRD = nullptr; - const FieldDecl *FD = nullptr; - - Base = Base->IgnoreParenImpCasts(); - - // Get the outer-most lexical RecordDecl. - if (const auto *DRE = dyn_cast(Base)) { - QualType Ty = DRE->getDecl()->getType(); - if (Ty->isPointerType()) - Ty = Ty->getPointeeType(); - - if (const auto *RD = Ty->getAsRecordDecl()) - OuterRD = RD->getOuterLexicalRecordContext(); - } else if (const auto *ME = dyn_cast(Base)) { - if (const ValueDecl *MD = ME->getMemberDecl()) { - OuterRD = MD->getDeclContext()->getOuterLexicalRecordContext(); - - const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = - getLangOpts().getStrictFlexArraysLevel(); - if (Decl::isFlexibleArrayMemberLike( - Ctx, MD, MD->getType(), StrictFlexArraysLevel, - /*IgnoreTemplateOrMacroSubstitution=*/true)) - // Base is referencing the FAM itself. - FD = dyn_cast(MD); - } - } - - if (!OuterRD) - return nullptr; - - if (!FD) { - const ValueDecl *VD = FindFlexibleArrayMemberField(Ctx, OuterRD); - FD = dyn_cast_if_present(VD); - if (!FD) - return nullptr; - } - - const auto *CBA = FD->getAttr(); - if (!CBA) - return nullptr; - - DeclarationName DName(CBA->getCountedByField()); - DeclContext::lookup_result Lookup = OuterRD->lookup(DName); - - if (Lookup.empty()) - return nullptr; - - return dyn_cast(Lookup.front()); -} - void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed) { assert(SanOpts.has(SanitizerKind::ArrayBounds) && "should not be called unless adding bounds checks"); + SanitizerScope SanScope(this); + const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel(); @@ -1081,8 +960,6 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base, if (!Bound) return; - SanitizerScope SanScope(this); - bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType(); llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned); llvm::Value *BoundVal = Builder.CreateIntCast(Bound, SizeTy, false); @@ -3156,7 +3033,7 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) { auto SL = E->getFunctionName(); assert(SL != nullptr && "No StringLiteral name in PredefinedExpr"); StringRef FnName = CurFn->getName(); - if (FnName.startswith("\01")) + if (FnName.starts_with("\01")) FnName = FnName.substr(1); StringRef NameItems[] = { PredefinedExpr::getIdentKindName(E->getIdentKind()), FnName}; diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 41ad2ddac30d2d3b45758fde246a4fa83891011e..6adf99531e30e38f25084ebfdb01f0980eb9f166 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1894,8 +1894,8 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { // initializer, since LLVM optimizers generally do not want to touch // shuffles. unsigned CurIdx = 0; - bool VIsUndefShuffle = false; - llvm::Value *V = llvm::UndefValue::get(VType); + bool VIsPoisonShuffle = false; + llvm::Value *V = llvm::PoisonValue::get(VType); for (unsigned i = 0; i != NumInitElements; ++i) { Expr *IE = E->getInit(i); Value *Init = Visit(IE); @@ -1915,16 +1915,16 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { llvm::ConstantInt *C = cast(EI->getIndexOperand()); Value *LHS = nullptr, *RHS = nullptr; if (CurIdx == 0) { - // insert into undef -> shuffle (src, undef) + // insert into poison -> shuffle (src, poison) // shufflemask must use an i32 Args.push_back(getAsInt32(C, CGF.Int32Ty)); Args.resize(ResElts, -1); LHS = EI->getVectorOperand(); RHS = V; - VIsUndefShuffle = true; - } else if (VIsUndefShuffle) { - // insert into undefshuffle && size match -> shuffle (v, src) + VIsPoisonShuffle = true; + } else if (VIsPoisonShuffle) { + // insert into poison shuffle && size match -> shuffle (v, src) llvm::ShuffleVectorInst *SVV = cast(V); for (unsigned j = 0; j != CurIdx; ++j) Args.push_back(getMaskElt(SVV, j, 0)); @@ -1933,7 +1933,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { LHS = cast(V)->getOperand(0); RHS = EI->getVectorOperand(); - VIsUndefShuffle = false; + VIsPoisonShuffle = false; } if (!Args.empty()) { V = Builder.CreateShuffleVector(LHS, RHS, Args); @@ -1944,7 +1944,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { } V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx), "vecinit"); - VIsUndefShuffle = false; + VIsPoisonShuffle = false; ++CurIdx; continue; } @@ -1962,9 +1962,9 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { if (OpTy->getNumElements() == ResElts) { for (unsigned j = 0; j != CurIdx; ++j) { - // If the current vector initializer is a shuffle with undef, merge + // If the current vector initializer is a shuffle with poison, merge // this shuffle directly into it. - if (VIsUndefShuffle) { + if (VIsPoisonShuffle) { Args.push_back(getMaskElt(cast(V), j, 0)); } else { Args.push_back(j); @@ -1974,7 +1974,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { Args.push_back(getMaskElt(SVI, j, Offset)); Args.resize(ResElts, -1); - if (VIsUndefShuffle) + if (VIsPoisonShuffle) V = cast(V)->getOperand(0); Init = SVOp; @@ -1997,12 +1997,12 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { Args.resize(ResElts, -1); } - // If V is undef, make sure it ends up on the RHS of the shuffle to aid + // If V is poison, make sure it ends up on the RHS of the shuffle to aid // merging subsequent shuffles into this one. if (CurIdx == 0) std::swap(V, Init); V = Builder.CreateShuffleVector(V, Init, Args, "vecinit"); - VIsUndefShuffle = isa(Init); + VIsPoisonShuffle = isa(Init); CurIdx += InitElts; } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 3e8a40e7540bef7060a4f5fe124250483e684c46..e887d35198b3c7b6e5b0e7962664c3b45a3951ed 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -182,10 +182,8 @@ void CGHLSLRuntime::finishCodeGen() { llvm::hlsl::ResourceKind RK = Buf.IsCBuffer ? llvm::hlsl::ResourceKind::CBuffer : llvm::hlsl::ResourceKind::TBuffer; - std::string TyName = - Buf.Name.str() + (Buf.IsCBuffer ? ".cb." : ".tb.") + "ty"; - addBufferResourceAnnotation(GV, TyName, RC, RK, /*IsROV=*/false, - Buf.Binding); + addBufferResourceAnnotation(GV, RC, RK, /*IsROV=*/false, + llvm::hlsl::ElementType::Invalid, Buf.Binding); } } @@ -194,10 +192,10 @@ CGHLSLRuntime::Buffer::Buffer(const HLSLBufferDecl *D) Binding(D->getAttr()) {} void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV, - llvm::StringRef TyName, llvm::hlsl::ResourceClass RC, llvm::hlsl::ResourceKind RK, bool IsROV, + llvm::hlsl::ElementType ET, BufferResBinding &Binding) { llvm::Module &M = CGM.getModule(); @@ -216,15 +214,62 @@ void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV, assert(false && "Unsupported buffer type!"); return; } - assert(ResourceMD != nullptr && "ResourceMD must have been set by the switch above."); llvm::hlsl::FrontendResource Res( - GV, TyName, RK, IsROV, Binding.Reg.value_or(UINT_MAX), Binding.Space); + GV, RK, ET, IsROV, Binding.Reg.value_or(UINT_MAX), Binding.Space); ResourceMD->addOperand(Res.getMetadata()); } +static llvm::hlsl::ElementType +calculateElementType(const ASTContext &Context, const clang::Type *ResourceTy) { + using llvm::hlsl::ElementType; + + // TODO: We may need to update this when we add things like ByteAddressBuffer + // that don't have a template parameter (or, indeed, an element type). + const auto *TST = ResourceTy->getAs(); + assert(TST && "Resource types must be template specializations"); + ArrayRef Args = TST->template_arguments(); + assert(!Args.empty() && "Resource has no element type"); + + // At this point we have a resource with an element type, so we can assume + // that it's valid or we would have diagnosed the error earlier. + QualType ElTy = Args[0].getAsType(); + + // We should either have a basic type or a vector of a basic type. + if (const auto *VecTy = ElTy->getAs()) + ElTy = VecTy->getElementType(); + + if (ElTy->isSignedIntegerType()) { + switch (Context.getTypeSize(ElTy)) { + case 16: + return ElementType::I16; + case 32: + return ElementType::I32; + case 64: + return ElementType::I64; + } + } else if (ElTy->isUnsignedIntegerType()) { + switch (Context.getTypeSize(ElTy)) { + case 16: + return ElementType::U16; + case 32: + return ElementType::U32; + case 64: + return ElementType::U64; + } + } else if (ElTy->isSpecificBuiltinType(BuiltinType::Half)) + return ElementType::F16; + else if (ElTy->isSpecificBuiltinType(BuiltinType::Float)) + return ElementType::F32; + else if (ElTy->isSpecificBuiltinType(BuiltinType::Double)) + return ElementType::F64; + + // TODO: We need to handle unorm/snorm float types here once we support them + llvm_unreachable("Invalid element type for resource"); +} + void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { const Type *Ty = D->getType()->getPointeeOrArrayElementType(); if (!Ty) @@ -239,10 +284,10 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { llvm::hlsl::ResourceClass RC = Attr->getResourceClass(); llvm::hlsl::ResourceKind RK = Attr->getResourceKind(); bool IsROV = Attr->getIsROV(); + llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty); - QualType QT(Ty, 0); BufferResBinding Binding(D->getAttr()); - addBufferResourceAnnotation(GV, QT.getAsString(), RC, RK, IsROV, Binding); + addBufferResourceAnnotation(GV, RC, RK, IsROV, ET, Binding); } CGHLSLRuntime::BufferResBinding::BufferResBinding( diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index bb500cb5c979f27d4e85d5440ae68aa207e69f19..bffefb66740a0010a999036293119227eca3d0f7 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -90,9 +90,9 @@ public: private: void addBufferResourceAnnotation(llvm::GlobalVariable *GV, - llvm::StringRef TyName, llvm::hlsl::ResourceClass RC, llvm::hlsl::ResourceKind RK, bool IsROV, + llvm::hlsl::ElementType ET, BufferResBinding &Binding); void addConstant(VarDecl *D, Buffer &CB); void addBufferDecls(const DeclContext *DC, Buffer &CB); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index ba52b23be018b85cda05422c1bb397788d32b07e..517f7cddebc1a2b58ff52858e9a65e34222d087a 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1850,7 +1850,7 @@ static bool hasObjCExceptionAttribute(ASTContext &Context, static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section) { if (CGM.getTriple().isOSBinFormatMachO() && - (Section.empty() || Section.startswith("__DATA"))) + (Section.empty() || Section.starts_with("__DATA"))) return llvm::GlobalValue::InternalLinkage; return llvm::GlobalValue::PrivateLinkage; } @@ -6162,7 +6162,7 @@ void CGObjCNonFragileABIMac::AddModuleClassList( // Section name is obtained by calling GetSectionName, which returns // sections in the __DATA segment on MachO. assert((!CGM.getTriple().isOSBinFormatMachO() || - SectionName.startswith("__DATA")) && + SectionName.starts_with("__DATA")) && "SectionName expected to start with __DATA on MachO"); llvm::GlobalVariable *GV = new llvm::GlobalVariable( CGM.getModule(), Init->getType(), false, diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 7f7e6f5306664446ccbfdbfbe40ec7de13f0a977..ea6645a39e83218fbd342464cd8b60dc2a60fdbd 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6811,8 +6811,10 @@ private: OpenMPMapClauseKind MapType, ArrayRef MapModifiers, ArrayRef MotionModifiers, OMPClauseMappableExprCommon::MappableExprComponentListRef Components, - MapCombinedInfoTy &CombinedInfo, StructRangeInfoTy &PartialStruct, - bool IsFirstComponentList, bool IsImplicit, + MapCombinedInfoTy &CombinedInfo, + MapCombinedInfoTy &StructBaseCombinedInfo, + StructRangeInfoTy &PartialStruct, bool IsFirstComponentList, + bool IsImplicit, bool GenerateAllInfoForClauses, const ValueDecl *Mapper = nullptr, bool ForDeviceAddr = false, const ValueDecl *BaseDecl = nullptr, const Expr *MapExpr = nullptr, ArrayRef @@ -7098,6 +7100,25 @@ private: bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous; bool IsPrevMemberReference = false; + // We need to check if we will be encountering any MEs. If we do not + // encounter any ME expression it means we will be mapping the whole struct. + // In that case we need to skip adding an entry for the struct to the + // CombinedInfo list and instead add an entry to the StructBaseCombinedInfo + // list only when generating all info for clauses. + bool IsMappingWholeStruct = true; + if (!GenerateAllInfoForClauses) { + IsMappingWholeStruct = false; + } else { + for (auto TempI = I; TempI != CE; ++TempI) { + const MemberExpr *PossibleME = + dyn_cast(TempI->getAssociatedExpression()); + if (PossibleME) { + IsMappingWholeStruct = false; + break; + } + } + } + for (; I != CE; ++I) { // If the current component is member of a struct (parent struct) mark it. if (!EncounteredME) { @@ -7317,21 +7338,41 @@ private: break; } llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression()); + // Skip adding an entry in the CurInfo of this combined entry if the + // whole struct is currently being mapped. The struct needs to be added + // in the first position before any data internal to the struct is being + // mapped. if (!IsMemberPointerOrAddr || (Next == CE && MapType != OMPC_MAP_unknown)) { - CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.getPointer()); - CombinedInfo.DevicePtrDecls.push_back(nullptr); - CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.getPointer()); - CombinedInfo.Sizes.push_back( - CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true)); - CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize - : 1); + if (!IsMappingWholeStruct) { + CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); + CombinedInfo.BasePointers.push_back(BP.getPointer()); + CombinedInfo.DevicePtrDecls.push_back(nullptr); + CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); + CombinedInfo.Pointers.push_back(LB.getPointer()); + CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( + Size, CGF.Int64Ty, /*isSigned=*/true)); + CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize + : 1); + } else { + StructBaseCombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); + StructBaseCombinedInfo.BasePointers.push_back(BP.getPointer()); + StructBaseCombinedInfo.DevicePtrDecls.push_back(nullptr); + StructBaseCombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); + StructBaseCombinedInfo.Pointers.push_back(LB.getPointer()); + StructBaseCombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( + Size, CGF.Int64Ty, /*isSigned=*/true)); + StructBaseCombinedInfo.NonContigInfo.Dims.push_back( + IsNonContiguous ? DimSize : 1); + } // If Mapper is valid, the last component inherits the mapper. bool HasMapper = Mapper && Next == CE; - CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr); + if (!IsMappingWholeStruct) + CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr); + else + StructBaseCombinedInfo.Mappers.push_back(HasMapper ? Mapper + : nullptr); // We need to add a pointer flag for each map that comes from the // same expression except for the first one. We also need to signal @@ -7363,7 +7404,10 @@ private: } } - CombinedInfo.Types.push_back(Flags); + if (!IsMappingWholeStruct) + CombinedInfo.Types.push_back(Flags); + else + StructBaseCombinedInfo.Types.push_back(Flags); } // If we have encountered a member expression so far, keep track of the @@ -7954,8 +7998,10 @@ private: for (const auto &Data : Info) { StructRangeInfoTy PartialStruct; - // Temporary generated information. + // Current struct information: MapCombinedInfoTy CurInfo; + // Current struct base information: + MapCombinedInfoTy StructBaseCurInfo; const Decl *D = Data.first; const ValueDecl *VD = cast_or_null(D); for (const auto &M : Data.second) { @@ -7965,29 +8011,55 @@ private: // Remember the current base pointer index. unsigned CurrentBasePointersIdx = CurInfo.BasePointers.size(); + unsigned StructBasePointersIdx = + StructBaseCurInfo.BasePointers.size(); CurInfo.NonContigInfo.IsNonContiguous = L.Components.back().isNonContiguous(); generateInfoForComponentList( L.MapType, L.MapModifiers, L.MotionModifiers, L.Components, - CurInfo, PartialStruct, /*IsFirstComponentList=*/false, - L.IsImplicit, L.Mapper, L.ForDeviceAddr, VD, L.VarRef); + CurInfo, StructBaseCurInfo, PartialStruct, + /*IsFirstComponentList=*/false, L.IsImplicit, + /*GenerateAllInfoForClauses*/ true, L.Mapper, L.ForDeviceAddr, VD, + L.VarRef); - // If this entry relates with a device pointer, set the relevant + // If this entry relates to a device pointer, set the relevant // declaration and add the 'return pointer' flag. if (L.ReturnDevicePointer) { - assert(CurInfo.BasePointers.size() > CurrentBasePointersIdx && + // Check whether a value was added to either CurInfo or + // StructBaseCurInfo and error if no value was added to either of + // them: + assert((CurrentBasePointersIdx < CurInfo.BasePointers.size() || + StructBasePointersIdx < + StructBaseCurInfo.BasePointers.size()) && "Unexpected number of mapped base pointers."); + // Choose a base pointer index which is always valid: const ValueDecl *RelevantVD = L.Components.back().getAssociatedDeclaration(); assert(RelevantVD && "No relevant declaration related with device pointer??"); - CurInfo.DevicePtrDecls[CurrentBasePointersIdx] = RelevantVD; - CurInfo.DevicePointers[CurrentBasePointersIdx] = - L.ForDeviceAddr ? DeviceInfoTy::Address : DeviceInfoTy::Pointer; - CurInfo.Types[CurrentBasePointersIdx] |= - OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM; + // If StructBaseCurInfo has been updated this iteration then work on + // the first new entry added to it i.e. make sure that when multiple + // values are added to any of the lists, the first value added is + // being modified by the assignments below (not the last value + // added). + if (StructBasePointersIdx < StructBaseCurInfo.BasePointers.size()) { + StructBaseCurInfo.DevicePtrDecls[StructBasePointersIdx] = + RelevantVD; + StructBaseCurInfo.DevicePointers[StructBasePointersIdx] = + L.ForDeviceAddr ? DeviceInfoTy::Address + : DeviceInfoTy::Pointer; + StructBaseCurInfo.Types[StructBasePointersIdx] |= + OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM; + } else { + CurInfo.DevicePtrDecls[CurrentBasePointersIdx] = RelevantVD; + CurInfo.DevicePointers[CurrentBasePointersIdx] = + L.ForDeviceAddr ? DeviceInfoTy::Address + : DeviceInfoTy::Pointer; + CurInfo.Types[CurrentBasePointersIdx] |= + OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM; + } } } } @@ -8034,17 +8106,24 @@ private: CurInfo.Mappers.push_back(nullptr); } } + + // Unify entries in one list making sure the struct mapping precedes the + // individual fields: + MapCombinedInfoTy UnionCurInfo; + UnionCurInfo.append(StructBaseCurInfo); + UnionCurInfo.append(CurInfo); + // If there is an entry in PartialStruct it means we have a struct with // individual members mapped. Emit an extra combined entry. if (PartialStruct.Base.isValid()) { - CurInfo.NonContigInfo.Dims.push_back(0); - emitCombinedEntry(CombinedInfo, CurInfo.Types, PartialStruct, + UnionCurInfo.NonContigInfo.Dims.push_back(0); + // Emit a combined entry: + emitCombinedEntry(CombinedInfo, UnionCurInfo.Types, PartialStruct, /*IsMapThis*/ !VD, OMPBuilder, VD); } - // We need to append the results of this capture to what we already - // have. - CombinedInfo.append(CurInfo); + // We need to append the results of this capture to what we already have. + CombinedInfo.append(UnionCurInfo); } // Append data for use_device_ptr clauses. CombinedInfo.append(UseDeviceDataCombinedInfo); @@ -8554,6 +8633,7 @@ public: // Associated with a capture, because the mapping flags depend on it. // Go through all of the elements with the overlapped elements. bool IsFirstComponentList = true; + MapCombinedInfoTy StructBaseCombinedInfo; for (const auto &Pair : OverlappedData) { const MapData &L = *Pair.getFirst(); OMPClauseMappableExprCommon::MappableExprComponentListRef Components; @@ -8568,7 +8648,8 @@ public: OverlappedComponents = Pair.getSecond(); generateInfoForComponentList( MapType, MapModifiers, std::nullopt, Components, CombinedInfo, - PartialStruct, IsFirstComponentList, IsImplicit, Mapper, + StructBaseCombinedInfo, PartialStruct, IsFirstComponentList, + IsImplicit, /*GenerateAllInfoForClauses*/ false, Mapper, /*ForDeviceAddr=*/false, VD, VarRef, OverlappedComponents); IsFirstComponentList = false; } @@ -8584,10 +8665,11 @@ public: L; auto It = OverlappedData.find(&L); if (It == OverlappedData.end()) - generateInfoForComponentList(MapType, MapModifiers, std::nullopt, - Components, CombinedInfo, PartialStruct, - IsFirstComponentList, IsImplicit, Mapper, - /*ForDeviceAddr=*/false, VD, VarRef); + generateInfoForComponentList( + MapType, MapModifiers, std::nullopt, Components, CombinedInfo, + StructBaseCombinedInfo, PartialStruct, IsFirstComponentList, + IsImplicit, /*GenerateAllInfoForClauses*/ false, Mapper, + /*ForDeviceAddr=*/false, VD, VarRef); IsFirstComponentList = false; } } diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index cbfa79e10bfefcc95eaeafdde2ea35a52e112081..868ef810f3c4e8c5d84c5b8b90d7d2f5738278f3 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -111,7 +111,7 @@ struct CGRecordLowering { /// Helper function to check if we are targeting AAPCS. bool isAAPCS() const { - return Context.getTargetInfo().getABI().startswith("aapcs"); + return Context.getTargetInfo().getABI().starts_with("aapcs"); } /// Helper function to check if the target machine is BigEndian. diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index a5cb80640641bb21cf81fa1cfab95dede66d981c..0f79a2e861d220474883cba554bc0779805c9677 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2548,7 +2548,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { ResultRegQualTys.push_back(QTy); ResultRegDests.push_back(Dest); - bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc"); + bool IsFlagReg = llvm::StringRef(OutputConstraint).starts_with("{@cc"); ResultRegIsFlagReg.push_back(IsFlagReg); llvm::Type *Ty = ConvertTypeForMem(QTy); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index ed426098ac691564edd4d2d23d7ffdee5e07c1b0..e362c9da51fe31d18bf6798443f9faa61087f6bf 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -6406,13 +6406,11 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, } } -static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF, - llvm::AtomicOrdering AO, const Expr *X, - const Expr *V, const Expr *R, - const Expr *E, const Expr *D, - const Expr *CE, bool IsXBinopExpr, - bool IsPostfixUpdate, bool IsFailOnly, - SourceLocation Loc) { +static void emitOMPAtomicCompareExpr( + CodeGenFunction &CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO, + const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *D, + const Expr *CE, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly, + SourceLocation Loc) { llvm::OpenMPIRBuilder &OMPBuilder = CGF.CGM.getOpenMPRuntime().getOMPBuilder(); @@ -6477,13 +6475,21 @@ static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF, R->getType().isVolatileQualified()}; } - CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare( - CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr, - IsPostfixUpdate, IsFailOnly)); + if (FailAO == llvm::AtomicOrdering::NotAtomic) { + // fail clause was not mentionend on the + // "#pragma omp atomic compare" construct. + CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare( + CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr, + IsPostfixUpdate, IsFailOnly)); + } else + CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare( + CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr, + IsPostfixUpdate, IsFailOnly, FailAO)); } static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, - llvm::AtomicOrdering AO, bool IsPostfixUpdate, + llvm::AtomicOrdering AO, + llvm::AtomicOrdering FailAO, bool IsPostfixUpdate, const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *UE, const Expr *D, const Expr *CE, bool IsXLHSInRHSPart, @@ -6504,12 +6510,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, IsXLHSInRHSPart, Loc); break; case OMPC_compare: { - emitOMPAtomicCompareExpr(CGF, AO, X, V, R, E, D, CE, IsXLHSInRHSPart, - IsPostfixUpdate, IsFailOnly, Loc); - break; - } - case OMPC_fail: { - //TODO + emitOMPAtomicCompareExpr(CGF, AO, FailAO, X, V, R, E, D, CE, + IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly, Loc); break; } default: @@ -6519,6 +6521,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { llvm::AtomicOrdering AO = llvm::AtomicOrdering::Monotonic; + // Fail Memory Clause Ordering. + llvm::AtomicOrdering FailAO = llvm::AtomicOrdering::NotAtomic; bool MemOrderingSpecified = false; if (S.getSingleClause()) { AO = llvm::AtomicOrdering::SequentiallyConsistent; @@ -6572,12 +6576,27 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { } } + if (KindsEncountered.contains(OMPC_compare) && + KindsEncountered.contains(OMPC_fail)) { + Kind = OMPC_compare; + const auto *FailClause = S.getSingleClause(); + if (FailClause) { + OpenMPClauseKind FailParameter = FailClause->getFailParameter(); + if (FailParameter == llvm::omp::OMPC_relaxed) + FailAO = llvm::AtomicOrdering::Monotonic; + else if (FailParameter == llvm::omp::OMPC_acquire) + FailAO = llvm::AtomicOrdering::Acquire; + else if (FailParameter == llvm::omp::OMPC_seq_cst) + FailAO = llvm::AtomicOrdering::SequentiallyConsistent; + } + } + LexicalScope Scope(*this, S.getSourceRange()); EmitStopPoint(S.getAssociatedStmt()); - emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(), - S.getR(), S.getExpr(), S.getUpdateExpr(), S.getD(), - S.getCondExpr(), S.isXLHSInRHSPart(), S.isFailOnly(), - S.getBeginLoc()); + emitOMPAtomicExpr(*this, Kind, AO, FailAO, S.isPostfixUpdate(), S.getX(), + S.getV(), S.getR(), S.getExpr(), S.getUpdateExpr(), + S.getD(), S.getCondExpr(), S.isXLHSInRHSPart(), + S.isFailOnly(), S.getBeginLoc()); } static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index bb6b1a3bc228cf9889bfc3655c48884c20410acb..f8038497d90a7bf88270116b48c9854027b59812 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -1139,8 +1139,7 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { // Strip off a leading diagnostic code if there is one. StringRef Msg = Err.getMessage(); - if (Msg.startswith("error: ")) - Msg = Msg.substr(7); + Msg.consume_front("error: "); unsigned DiagID = CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 618e78809db408b634536f6078ee4094c272ceeb..751d8110b13dfd06be4de4befc63e0cfefdd5d64 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3022,19 +3022,6 @@ public: void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed); - // Find a struct's flexible array member. It may be embedded inside multiple - // sub-structs, but must still be the last field. - const ValueDecl *FindFlexibleArrayMemberField(ASTContext &Ctx, - const RecordDecl *RD); - - /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns - /// \p nullptr if either the attribute or the field doesn't exist. - const ValueDecl *FindCountedByField(const Expr *Base); - - /// Build an expression accessing the "counted_by" field. - const Expr *BuildCountedByFieldExpr(const Expr *Base, - const ValueDecl *CountedByVD); - llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre); ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, @@ -4830,9 +4817,6 @@ private: llvm::Value *EmittedE, bool IsDynamic); - llvm::Value *emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, - llvm::IntegerType *ResType); - void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D, Address Loc); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index b931a81bc00871b6d1de5fc0919e64467324b6cb..d78f2594a23764cf3da10d1b296eacd60784c27d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -225,9 +225,9 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { StringRef ABIStr = Target.getABI(); unsigned XLen = Target.getPointerWidth(LangAS::Default); unsigned ABIFLen = 0; - if (ABIStr.endswith("f")) + if (ABIStr.ends_with("f")) ABIFLen = 32; - else if (ABIStr.endswith("d")) + else if (ABIStr.ends_with("d")) ABIFLen = 64; return createRISCVTargetCodeGenInfo(CGM, XLen, ABIFLen); } @@ -308,9 +308,9 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::loongarch64: { StringRef ABIStr = Target.getABI(); unsigned ABIFRLen = 0; - if (ABIStr.endswith("f")) + if (ABIStr.ends_with("f")) ABIFRLen = 32; - else if (ABIStr.endswith("d")) + else if (ABIStr.ends_with("d")) ABIFRLen = 64; return createLoongArchTargetCodeGenInfo( CGM, Target.getPointerWidth(LangAS::Default), ABIFRLen); @@ -995,12 +995,7 @@ void CodeGenModule::Release() { uint32_t(CLANG_VERSION_MINOR)); getModule().addModuleFlag(llvm::Module::Warning, "zos_product_patchlevel", uint32_t(CLANG_VERSION_PATCHLEVEL)); - std::string ProductId; -#ifdef CLANG_VENDOR - ProductId = #CLANG_VENDOR; -#else - ProductId = "clang"; -#endif + std::string ProductId = getClangVendor() + "clang"; getModule().addModuleFlag(llvm::Module::Error, "zos_product_id", llvm::MDString::get(VMContext, ProductId)); @@ -1111,6 +1106,9 @@ void CodeGenModule::Release() { if (LangOpts.BranchTargetEnforcement) getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement", 1); + if (LangOpts.BranchProtectionPAuthLR) + getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", + 1); if (LangOpts.hasSignReturnAddress()) getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1); if (LangOpts.isSignReturnAddressScopeAll()) @@ -1715,7 +1713,7 @@ static void AppendTargetMangling(const CodeGenModule &CGM, llvm::sort(Info.Features, [&Target](StringRef LHS, StringRef RHS) { // Multiversioning doesn't allow "no-${feature}", so we can // only have "+" prefixes here. - assert(LHS.startswith("+") && RHS.startswith("+") && + assert(LHS.starts_with("+") && RHS.starts_with("+") && "Features should always have a prefix."); return Target.multiVersionSortPriority(LHS.substr(1)) > Target.multiVersionSortPriority(RHS.substr(1)); @@ -1769,7 +1767,7 @@ static void AppendTargetClonesMangling(const CodeGenModule &CGM, } else { Out << '.'; StringRef FeatureStr = Attr->getFeatureStr(VersionIndex); - if (FeatureStr.startswith("arch=")) + if (FeatureStr.starts_with("arch=")) Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1); else Out << FeatureStr; @@ -3828,7 +3826,7 @@ namespace { if (!BuiltinID || !BI.isLibFunction(BuiltinID)) return false; StringRef BuiltinName = BI.getName(BuiltinID); - if (BuiltinName.startswith("__builtin_") && + if (BuiltinName.starts_with("__builtin_") && Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) { return true; } @@ -4164,7 +4162,7 @@ void CodeGenModule::emitMultiVersionFunctions() { Feature.push_back(CurFeat.trim()); } } else { - if (Version.startswith("arch=")) + if (Version.starts_with("arch=")) Architecture = Version.drop_front(sizeof("arch=") - 1); else if (Version != "default") Feature.push_back(Version); diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index b16358ee117ae20707f767dcff0c58af3a89a437..56411e2240e505ea617587199fe28de761f60509 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1623,8 +1623,12 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName, OS << "Gap,"; break; case CounterMappingRegion::BranchRegion: + case CounterMappingRegion::MCDCBranchRegion: OS << "Branch,"; break; + case CounterMappingRegion::MCDCDecisionRegion: + OS << "Decision,"; + break; } OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index be5145daa00b7f5fa2f53b80c8ff4cc08acdf9ce..7102d190fe008bd47fa74933e39a8739b4c19ff5 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -136,6 +136,8 @@ public: Fn->addFnAttr("branch-target-enforcement", BPI.BranchTargetEnforcement ? "true" : "false"); + Fn->addFnAttr("branch-protection-pauth-lr", + BPI.BranchProtectionPAuthLR ? "true" : "false"); } bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index 7b2c31139b0b2a3275fdd11548203a3f5c7c616d..63b9a1fdb988ceba4142c412bbbd1e0c777ac196 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -324,13 +324,6 @@ ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, return ABIArgInfo::getDirect(); } - // Pass 128-bit/256-bit vector values via vector registers directly. - if (Ty->isVectorType() && (((getContext().getTypeSize(Ty) == 128) && - (getTarget().hasFeature("lsx"))) || - ((getContext().getTypeSize(Ty) == 256) && - getTarget().hasFeature("lasx")))) - return ABIArgInfo::getDirect(); - // Complex types for the *f or *d ABI must be passed directly rather than // using CoerceAndExpand. if (IsFixed && Ty->isComplexType() && FRLen && FARsLeft >= 2) { diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 8bacba65617e431c1e2911a87284875de2e0920d..cf068cbc4fcd36806f5f2d452a216aac56b8ed2a 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -146,14 +146,14 @@ static llvm::Type *getSPIRVImageType(llvm::LLVMContext &Ctx, StringRef BaseType, // Choose the dimension of the image--this corresponds to the Dim enum in // SPIR-V (first integer parameter of OpTypeImage). - if (OpenCLName.startswith("image2d")) + if (OpenCLName.starts_with("image2d")) IntParams[0] = 1; // 1D - else if (OpenCLName.startswith("image3d")) + else if (OpenCLName.starts_with("image3d")) IntParams[0] = 2; // 2D else if (OpenCLName == "image1d_buffer") IntParams[0] = 5; // Buffer else - assert(OpenCLName.startswith("image1d") && "Unknown image type"); + assert(OpenCLName.starts_with("image1d") && "Unknown image type"); // Set the other integer parameters of OpTypeImage if necessary. Note that the // OpenCL image types don't provide any information for the Sampled or diff --git a/clang/lib/Driver/Distro.cpp b/clang/lib/Driver/Distro.cpp index 36f828f8cae26d31193f925ed8b07f15b321923f..a7e7f169dc1419e3d64c7acbe047d56753952afe 100644 --- a/clang/lib/Driver/Distro.cpp +++ b/clang/lib/Driver/Distro.cpp @@ -34,7 +34,7 @@ static Distro::DistroType DetectOsRelease(llvm::vfs::FileSystem &VFS) { // Obviously this can be improved a lot. for (StringRef Line : Lines) - if (Version == Distro::UnknownDistro && Line.startswith("ID=")) + if (Version == Distro::UnknownDistro && Line.starts_with("ID=")) Version = llvm::StringSwitch(Line.substr(3)) .Case("alpine", Distro::AlpineLinux) .Case("fedora", Distro::Fedora) @@ -60,7 +60,7 @@ static Distro::DistroType DetectLsbRelease(llvm::vfs::FileSystem &VFS) { for (StringRef Line : Lines) if (Version == Distro::UnknownDistro && - Line.startswith("DISTRIB_CODENAME=")) + Line.starts_with("DISTRIB_CODENAME=")) Version = llvm::StringSwitch(Line.substr(17)) .Case("hardy", Distro::UbuntuHardy) .Case("intrepid", Distro::UbuntuIntrepid) @@ -119,10 +119,10 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) { if (File) { StringRef Data = File.get()->getBuffer(); - if (Data.startswith("Fedora release")) + if (Data.starts_with("Fedora release")) return Distro::Fedora; - if (Data.startswith("Red Hat Enterprise Linux") || - Data.startswith("CentOS") || Data.startswith("Scientific Linux")) { + if (Data.starts_with("Red Hat Enterprise Linux") || + Data.starts_with("CentOS") || Data.starts_with("Scientific Linux")) { if (Data.contains("release 7")) return Distro::RHEL7; else if (Data.contains("release 6")) @@ -182,7 +182,7 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) { SmallVector Lines; Data.split(Lines, "\n"); for (const StringRef &Line : Lines) { - if (!Line.trim().startswith("VERSION")) + if (!Line.trim().starts_with("VERSION")) continue; std::pair SplitLine = Line.split('='); // Old versions have split VERSION and PATCHLEVEL diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f392f6794f857e62df637602027a56e99ad2fb9e..9b2f2a374809835e03209ae1c8ceda1ec6265aa1 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -86,6 +86,7 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" +#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" @@ -670,10 +671,15 @@ static llvm::Triple computeTargetTriple(const Driver &D, if (Args.hasArg(options::OPT_march_EQ) || Args.hasArg(options::OPT_mcpu_EQ)) { StringRef ArchName = tools::riscv::getRISCVArch(Args, Target); - if (ArchName.starts_with_insensitive("rv32")) - Target.setArch(llvm::Triple::riscv32); - else if (ArchName.starts_with_insensitive("rv64")) - Target.setArch(llvm::Triple::riscv64); + auto ISAInfo = llvm::RISCVISAInfo::parseArchString( + ArchName, /*EnableExperimentalExtensions=*/true); + if (!llvm::errorToBool(ISAInfo.takeError())) { + unsigned XLen = (*ISAInfo)->getXLen(); + if (XLen == 32) + Target.setArch(llvm::Triple::riscv32); + else if (XLen == 64) + Target.setArch(llvm::Triple::riscv64); + } } } @@ -1451,7 +1457,7 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::aarch64_32: - if (TC.getTriple().getEnvironmentName().startswith("eabi")) { + if (TC.getTriple().getEnvironmentName().starts_with("eabi")) { Diag(diag::warn_target_unrecognized_env) << TargetTriple << (TC.getTriple().getArchName().str() + "-none-elf"); @@ -1540,7 +1546,7 @@ bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename, for (fs::directory_iterator File(CrashDiagDir, EC), FileEnd; File != FileEnd && !EC; File.increment(EC)) { StringRef FileName = path::filename(File->path()); - if (!FileName.startswith(Name)) + if (!FileName.starts_with(Name)) continue; if (fs::status(File->path(), FileStatus)) continue; @@ -1551,7 +1557,7 @@ bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename, // The first line should start with "Process:", otherwise this isn't a real // .crash file. StringRef Data = CrashFile.get()->getBuffer(); - if (!Data.startswith("Process:")) + if (!Data.starts_with("Process:")) continue; // Parse parent process pid line, e.g: "Parent Process: clang-4.0 [79141]" size_t ParentProcPos = Data.find("Parent Process:"); @@ -1780,7 +1786,7 @@ void Driver::generateCompilationDiagnostics( ReproCrashFilename = TempFile; llvm::sys::path::replace_extension(ReproCrashFilename, ".crash"); } - if (StringRef(TempFile).endswith(".cache")) { + if (StringRef(TempFile).ends_with(".cache")) { // In some cases (modules) we'll dump extra data to help with reproducing // the crash into a directory next to the output. VFS = llvm::sys::path::filename(TempFile); @@ -2001,7 +2007,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const { // Distinguish "--autocomplete=-someflag" and "--autocomplete=-someflag," // because the latter indicates that the user put space before pushing tab // which should end up in a file completion. - const bool HasSpace = PassedFlags.endswith(","); + const bool HasSpace = PassedFlags.ends_with(","); // Parse PassedFlags by "," as all the command-line flags are passed to this // function separated by "," @@ -2041,7 +2047,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const { // When flag ends with '=' and there was no value completion, return empty // string and fall back to the file autocompletion. - if (SuggestedCompletions.empty() && !Cur.endswith("=")) { + if (SuggestedCompletions.empty() && !Cur.ends_with("=")) { // If the flag is in the form of "--autocomplete=-foo", // we were requested to print out all option names that start with "-foo". // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". @@ -2053,7 +2059,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const { // TODO: Find a good way to add them to OptTable instead and them remove // this code. for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) - if (S.startswith(Cur)) + if (S.starts_with(Cur)) SuggestedCompletions.push_back(std::string(S)); } @@ -2535,7 +2541,7 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, // so we can't downgrade diagnostics for `/GR-` from an error to a warning // in cc mode. (We can in cl mode because cl.exe itself only warns on // unknown flags.) - if (IsCLMode() && Ty == types::TY_Object && !Value.startswith("/")) + if (IsCLMode() && Ty == types::TY_Object && !Value.starts_with("/")) return true; Diag(clang::diag::err_drv_no_such_file) << Value; @@ -6565,7 +6571,7 @@ llvm::StringRef clang::driver::getDriverMode(StringRef ProgName, getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName(); llvm::StringRef Opt; for (StringRef Arg : Args) { - if (!Arg.startswith(OptName)) + if (!Arg.starts_with(OptName)) continue; Opt = Arg; } @@ -6606,7 +6612,7 @@ llvm::Error driver::expandResponseFiles(SmallVectorImpl &Args, else Tokenizer = &llvm::cl::TokenizeGNUCommandLine; - if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1")) + if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with("-cc1")) MarkEOLs = false; llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer); @@ -6620,7 +6626,7 @@ llvm::Error driver::expandResponseFiles(SmallVectorImpl &Args, // If -cc1 came from a response file, remove the EOL sentinels. auto FirstArg = llvm::find_if(llvm::drop_begin(Args), [](const char *A) { return A != nullptr; }); - if (FirstArg != Args.end() && StringRef(*FirstArg).startswith("-cc1")) { + if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with("-cc1")) { // If -cc1 came from a response file, remove the EOL sentinels. if (MarkEOLs) { auto newEnd = std::remove(Args.begin(), Args.end(), nullptr); diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp index 203400440f9f61f13fe60023cb93382654fed0cf..a6c1581be796261ebc1530dd3460b44d6e215507 100644 --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -95,10 +95,10 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, // These flags are treated as a single argument (e.g., -F). StringRef FlagRef(Flag); - IsInclude = FlagRef.startswith("-F") || FlagRef.startswith("-I"); + IsInclude = FlagRef.starts_with("-F") || FlagRef.starts_with("-I"); if (IsInclude) return !HaveCrashVFS; - if (FlagRef.startswith("-fmodules-cache-path=")) + if (FlagRef.starts_with("-fmodules-cache-path=")) return true; SkipNum = 0; @@ -185,8 +185,8 @@ rewriteIncludes(const llvm::ArrayRef &Args, size_t Idx, SmallString<128> NewInc; if (NumArgs == 1) { StringRef FlagRef(Args[Idx + NumArgs - 1]); - assert((FlagRef.startswith("-F") || FlagRef.startswith("-I")) && - "Expecting -I or -F"); + assert((FlagRef.starts_with("-F") || FlagRef.starts_with("-I")) && + "Expecting -I or -F"); StringRef Inc = FlagRef.slice(2, StringRef::npos); if (getAbsPath(Inc, NewInc)) { SmallString<128> NewArg(FlagRef.slice(0, 2)); diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index ab19166f18c2dcf96187eb36b62b02d8edcc677b..96a57927339a970d344d1a7eafdf74bca742eea9 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -315,7 +315,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { for (const auto &DS : DriverSuffixes) { StringRef Suffix(DS.Suffix); - if (ProgName.endswith(Suffix)) { + if (ProgName.ends_with(Suffix)) { Pos = ProgName.size() - Suffix.size(); return &DS; } @@ -345,7 +345,7 @@ static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { // added via -target as implicit first argument. const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos); - if (!DS && ProgName.endswith(".exe")) { + if (!DS && ProgName.ends_with(".exe")) { // Try again after stripping the executable suffix: // clang++.exe -> clang++ ProgName = ProgName.drop_back(StringRef(".exe").size()); diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index aed8734b2bab0ffe77caa3807bdba74849d9f25f..e6126ff62db3c99e1b6617c54da898edb4e5f554 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -88,7 +88,7 @@ static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs) { for (size_t i = 0, Size = CmdArgs.size(); i < Size; ++i) { llvm::StringRef ArgString(CmdArgs[i]); - if (ArgString.startswith("-bE:") || ArgString.startswith("-bexport:") || + if (ArgString.starts_with("-bE:") || ArgString.starts_with("-bexport:") || ArgString == "-bexpall" || ArgString == "-bexpfull") return true; @@ -96,8 +96,8 @@ static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs) { if (ArgString == "-b" && i + 1 < Size) { ++i; llvm::StringRef ArgNextString(CmdArgs[i]); - if (ArgNextString.startswith("E:") || - ArgNextString.startswith("export:") || ArgNextString == "expall" || + if (ArgNextString.starts_with("E:") || + ArgNextString.starts_with("export:") || ArgNextString == "expall" || ArgNextString == "expfull") return true; } @@ -328,6 +328,12 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } + if (D.IsFlangMode()) { + addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); + addFortranRuntimeLibs(ToolChain, Args, CmdArgs); + CmdArgs.push_back("-lm"); + CmdArgs.push_back("-lpthread"); + } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), Exec, CmdArgs, Inputs, Output)); diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index cad206ea4df1bc5c4c0e032dd40d90a57f1a2dd1..56f06fc5fccb7eb75ffec08dc4fce6fe4c61f0cc 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -49,7 +49,7 @@ RocmInstallationDetector::findSPACKPackage(const Candidate &Cand, FileEnd; File != FileEnd && !EC; File.increment(EC)) { llvm::StringRef FileName = llvm::sys::path::filename(File->path()); - if (FileName.startswith(Prefix)) { + if (FileName.starts_with(Prefix)) { SubDirs.push_back(FileName); if (SubDirs.size() > 1) break; @@ -84,13 +84,13 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { !EC && LI != LE; LI = LI.increment(EC)) { StringRef FilePath = LI->path(); StringRef FileName = llvm::sys::path::filename(FilePath); - if (!FileName.endswith(Suffix)) + if (!FileName.ends_with(Suffix)) continue; StringRef BaseName; - if (FileName.endswith(Suffix2)) + if (FileName.ends_with(Suffix2)) BaseName = FileName.drop_back(Suffix2.size()); - else if (FileName.endswith(Suffix)) + else if (FileName.ends_with(Suffix)) BaseName = FileName.drop_back(Suffix.size()); const StringRef ABIVersionPrefix = "oclc_abi_version_"; @@ -124,7 +124,7 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { WavefrontSize64.On = FilePath; } else if (BaseName == "oclc_wavefrontsize64_off") { WavefrontSize64.Off = FilePath; - } else if (BaseName.startswith(ABIVersionPrefix)) { + } else if (BaseName.starts_with(ABIVersionPrefix)) { unsigned ABIVersionNumber; if (BaseName.drop_front(ABIVersionPrefix.size()) .getAsInteger(/*Redex=*/0, ABIVersionNumber)) @@ -134,7 +134,7 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { // Process all bitcode filenames that look like // ocl_isa_version_XXX.amdgcn.bc const StringRef DeviceLibPrefix = "oclc_isa_version_"; - if (!BaseName.startswith(DeviceLibPrefix)) + if (!BaseName.starts_with(DeviceLibPrefix)) continue; StringRef IsaVersionNumber = @@ -230,7 +230,7 @@ RocmInstallationDetector::getInstallationPathCandidates() { // /llvm-amdgpu--/bin directory. // We only consider the parent directory of llvm-amdgpu package as ROCm // installation candidate for SPACK. - if (ParentName.startswith("llvm-amdgpu-")) { + if (ParentName.starts_with("llvm-amdgpu-")) { auto SPACKPostfix = ParentName.drop_front(strlen("llvm-amdgpu-")).split('-'); auto SPACKReleaseStr = SPACKPostfix.first; @@ -243,7 +243,7 @@ RocmInstallationDetector::getInstallationPathCandidates() { // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin // Some versions of the aomp package install to /opt/rocm/aomp/bin - if (ParentName == "llvm" || ParentName.startswith("aomp")) + if (ParentName == "llvm" || ParentName.starts_with("aomp")) ParentDir = llvm::sys::path::parent_path(ParentDir); return Candidate(ParentDir.str(), /*StrictChecking=*/true); @@ -292,7 +292,7 @@ RocmInstallationDetector::getInstallationPathCandidates() { FileEnd; File != FileEnd && !EC; File.increment(EC)) { llvm::StringRef FileName = llvm::sys::path::filename(File->path()); - if (!FileName.startswith("rocm-")) + if (!FileName.starts_with("rocm-")) continue; if (LatestROCm.empty()) { LatestROCm = FileName.str(); diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 097258b16924442abf7b067343eea81d9c8cb0ec..912df79417ae21e4892251960d7b05640d547a93 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -228,7 +228,7 @@ getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, if (MtuneLowerCase == "native") MtuneLowerCase = std::string(llvm::sys::getHostCPUName()); if (MtuneLowerCase == "cyclone" || - StringRef(MtuneLowerCase).startswith("apple")) { + StringRef(MtuneLowerCase).starts_with("apple")) { Features.push_back("+zcm"); Features.push_back("+zcz"); } @@ -262,7 +262,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, for (const auto *A : Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) for (StringRef Value : A->getValues()) - if (Value.startswith("-march=")) + if (Value.starts_with("-march=")) WaMArch = Value.substr(7); // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or // "-Xassembler -march" is detected. Otherwise it may return false diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index f1d7aeb555f8bd0974cc5790cd1391d27fa9c5fe..25470db2b6cebd708bb7803299b38aa43a600cf1 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -67,9 +67,9 @@ void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch, // Use getValues because -Wa can have multiple arguments // e.g. -Wa,-mcpu=foo,-mcpu=bar for (StringRef Value : A->getValues()) { - if (Value.startswith("-mcpu=")) + if (Value.starts_with("-mcpu=")) CPU = Value.substr(6); - if (Value.startswith("-march=")) + if (Value.starts_with("-march=")) Arch = Value.substr(7); } } @@ -285,9 +285,9 @@ void arm::setArchNameInTriple(const Driver &D, const ArgList &Args, // There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm. if (Value == "-mthumb") IsThumb = true; - else if (Value.startswith("-march=")) + else if (Value.starts_with("-march=")) WaMArch = Value.substr(7); - else if (Value.startswith("-mcpu=")) + else if (Value.starts_with("-mcpu=")) WaMCPU = Value.substr(6); } } @@ -528,13 +528,13 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, // We use getValues here because you can have many options per -Wa // We will keep the last one we find for each of these for (StringRef Value : A->getValues()) { - if (Value.startswith("-mfpu=")) { + if (Value.starts_with("-mfpu=")) { WaFPU = std::make_pair(A, Value.substr(6)); - } else if (Value.startswith("-mcpu=")) { + } else if (Value.starts_with("-mcpu=")) { WaCPU = std::make_pair(A, Value.substr(6)); - } else if (Value.startswith("-mhwdiv=")) { + } else if (Value.starts_with("-mhwdiv=")) { WaHDiv = std::make_pair(A, Value.substr(8)); - } else if (Value.startswith("-march=")) { + } else if (Value.starts_with("-march=")) { WaArch = std::make_pair(A, Value.substr(7)); } } @@ -796,7 +796,7 @@ fp16_fml_fallthrough: // Propagate frame-chain model selection if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) { StringRef FrameChainOption = A->getValue(); - if (FrameChainOption.startswith("aapcs")) + if (FrameChainOption.starts_with("aapcs")) Features.push_back("+aapcs-frame-chain"); if (FrameChainOption == "aapcs+leaf") Features.push_back("+aapcs-frame-chain-leaf"); diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 0b696111e7d712382b68c520f041b10babdb5a58..0717e3b813e1e23d14882485efd6cd4540536899 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -45,6 +45,10 @@ static bool getArchFeatures(const Driver &D, StringRef Arch, (*ISAInfo)->toFeatures( Features, [&Args](const Twine &Str) { return Args.MakeArgString(Str); }, /*AddAllExtensions=*/true); + + if (EnableExperimentalExtensions) + Features.push_back(Args.MakeArgString("+experimental")); + return true; } @@ -163,13 +167,6 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("-relax"); } - // GCC Compatibility: -mno-save-restore is default, unless -msave-restore is - // specified. - if (Args.hasFlag(options::OPT_msave_restore, options::OPT_mno_save_restore, false)) - Features.push_back("+save-restore"); - else - Features.push_back("-save-restore"); - // -mno-unaligned-access is default, unless -munaligned-access is specified. AddTargetFeature(Args, Features, options::OPT_munaligned_access, options::OPT_mno_unaligned_access, "fast-unaligned-access"); @@ -218,10 +215,8 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) { auto ParseResult = llvm::RISCVISAInfo::parseArchString( Arch, /* EnableExperimentalExtension */ true); - if (!ParseResult) - // Ignore parsing error, just go 3rd step. - consumeError(ParseResult.takeError()); - else + // Ignore parsing error, just go 3rd step. + if (!llvm::errorToBool(ParseResult.takeError())) return (*ParseResult)->computeDefaultABI(); // 3. Choose a default based on the triple diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index 3e51b2b5ce8642e0ac08afc98617e96b630e2816..53e26a9f8e229e4c3814d83c639bcda34911c00c 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -234,15 +234,13 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, A->claim(); // Skip over "-m". - assert(Name.startswith("m") && "Invalid feature name."); + assert(Name.starts_with("m") && "Invalid feature name."); Name = Name.substr(1); - bool IsNegative = Name.startswith("no-"); - if (IsNegative) - Name = Name.substr(3); + bool IsNegative = Name.consume_front("no-"); #ifndef NDEBUG - assert(Name.startswith("avx10.") && "Invalid AVX10 feature name."); + assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name."); StringRef Version, Width; std::tie(Version, Width) = Name.substr(6).split('-'); assert(Version == "1" && "Invalid AVX10 feature name."); @@ -260,7 +258,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, A->claim(); // Skip over "-m". - assert(Name.startswith("m") && "Invalid feature name."); + assert(Name.starts_with("m") && "Invalid feature name."); Name = Name.substr(1); // Replace -mgeneral-regs-only with -x87, -mmx, -sse @@ -269,7 +267,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, continue; } - bool IsNegative = Name.startswith("no-"); + bool IsNegative = Name.starts_with("no-"); if (A->getOption().matches(options::OPT_mapx_features_EQ) || A->getOption().matches(options::OPT_mno_apx_features_EQ)) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f95f3227aba7d03bb4956b62f39569ce6ee49768..acfa119805068d23848bca353baf4a4c3fb4416f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -223,7 +223,7 @@ static void ParseMRecip(const Driver &D, const ArgList &Args, for (unsigned i = 0; i != NumOptions; ++i) { StringRef Val = A->getValue(i); - bool IsDisabled = Val.startswith(DisabledPrefixIn); + bool IsDisabled = Val.starts_with(DisabledPrefixIn); // Ignore the disablement token for string matching. if (IsDisabled) Val = Val.substr(1); @@ -433,7 +433,7 @@ static void addDebugObjectName(const ArgList &Args, ArgStringList &CmdArgs, const char *OutputFileName) { // No need to generate a value for -object-file-name if it was provided. for (auto *Arg : Args.filtered(options::OPT_Xclang)) - if (StringRef(Arg->getValue()).startswith("-object-file-name")) + if (StringRef(Arg->getValue()).starts_with("-object-file-name")) return; if (Args.hasArg(options::OPT_object_file_name_EQ)) @@ -940,7 +940,7 @@ static void handleAMDGPUCodeObjectVersionOptions(const Driver &D, static bool hasClangPchSignature(const Driver &D, StringRef Path) { if (llvm::ErrorOr> MemBuf = D.getVFS().getBufferForFile(Path)) - return (*MemBuf)->getBuffer().startswith("CPCH"); + return (*MemBuf)->getBuffer().starts_with("CPCH"); return false; } @@ -1497,7 +1497,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, << Triple.getArchName(); StringRef Scope, Key; - bool IndirectBranches; + bool IndirectBranches, BranchProtectionPAuthLR; if (A->getOption().matches(options::OPT_msign_return_address_EQ)) { Scope = A->getValue(); @@ -1506,6 +1506,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, << A->getSpelling() << Scope; Key = "a_key"; IndirectBranches = false; + BranchProtectionPAuthLR = false; } else { StringRef DiagMsg; llvm::ARM::ParsedBranchProtection PBP; @@ -1517,6 +1518,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, << "b-key" << A->getAsString(Args); Scope = PBP.Scope; Key = PBP.Key; + BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; IndirectBranches = PBP.BranchTargetEnforcement; } @@ -1525,6 +1527,9 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, if (!Scope.equals("none")) CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); + if (BranchProtectionPAuthLR) + CmdArgs.push_back( + Args.MakeArgString(Twine("-mbranch-protection-pauth-lr"))); if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); } @@ -1715,7 +1720,7 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, Val.equals("256+") || Val.equals("512+") || Val.equals("1024+") || Val.equals("2048+")) { unsigned Bits = 0; - if (Val.endswith("+")) + if (Val.ends_with("+")) Val = Val.substr(0, Val.size() - 1); else { bool Invalid = Val.getAsInteger(10, Bits); (void)Invalid; @@ -2067,12 +2072,9 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args, StringRef Arch = riscv::getRISCVArch(Args, Triple); auto ISAInfo = llvm::RISCVISAInfo::parseArchString( Arch, /*EnableExperimentalExtensions*/ true); - if (!ISAInfo) { - // Ignore parsing error. - consumeError(ISAInfo.takeError()); - } else { + // Ignore parsing error. + if (!errorToBool(ISAInfo.takeError())) MinVLen = (*ISAInfo)->getMinVLen(); - } // If the value is "zvl", use MinVLen from march. Otherwise, try to parse // as integer as long as we have a MinVLen. @@ -2503,7 +2505,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, case llvm::Triple::thumbeb: case llvm::Triple::arm: case llvm::Triple::armeb: - if (Value.startswith("-mimplicit-it=")) { + if (Value.starts_with("-mimplicit-it=")) { // Only store the value; the last value set takes effect. ImplicitIt = Value.split("=").second; if (CheckARMImplicitITArg(ImplicitIt)) @@ -2528,12 +2530,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back("-use-tcc-in-div"); continue; } - if (Value.startswith("-msoft-float")) { + if (Value.starts_with("-msoft-float")) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back("+soft-float"); continue; } - if (Value.startswith("-mhard-float")) { + if (Value.starts_with("-mhard-float")) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back("-soft-float"); continue; @@ -2570,8 +2572,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back("-massembler-no-warn"); } else if (Value == "--noexecstack") { UseNoExecStack = true; - } else if (Value.startswith("-compress-debug-sections") || - Value.startswith("--compress-debug-sections") || + } else if (Value.starts_with("-compress-debug-sections") || + Value.starts_with("--compress-debug-sections") || Value == "-nocompress-debug-sections" || Value == "--nocompress-debug-sections") { CmdArgs.push_back(Value.data()); @@ -2581,13 +2583,13 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } else if (Value == "-mrelax-relocations=no" || Value == "--mrelax-relocations=no") { UseRelaxRelocations = false; - } else if (Value.startswith("-I")) { + } else if (Value.starts_with("-I")) { CmdArgs.push_back(Value.data()); // We need to consume the next argument if the current arg is a plain // -I. The next arg will be the include directory. if (Value == "-I") TakeNextArg = true; - } else if (Value.startswith("-gdwarf-")) { + } else if (Value.starts_with("-gdwarf-")) { // "-gdwarf-N" options are not cc1as options. unsigned DwarfVersion = DwarfVersionNum(Value); if (DwarfVersion == 0) { // Send it onward, and let cc1as complain. @@ -2597,30 +2599,30 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, llvm::codegenoptions::DebugInfoConstructor, DwarfVersion, llvm::DebuggerKind::Default); } - } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") || - Value.startswith("-mhwdiv") || Value.startswith("-march")) { + } else if (Value.starts_with("-mcpu") || Value.starts_with("-mfpu") || + Value.starts_with("-mhwdiv") || Value.starts_with("-march")) { // Do nothing, we'll validate it later. } else if (Value == "-defsym") { - if (A->getNumValues() != 2) { - D.Diag(diag::err_drv_defsym_invalid_format) << Value; - break; - } - const char *S = A->getValue(1); - auto Pair = StringRef(S).split('='); - auto Sym = Pair.first; - auto SVal = Pair.second; - - if (Sym.empty() || SVal.empty()) { - D.Diag(diag::err_drv_defsym_invalid_format) << S; - break; - } - int64_t IVal; - if (SVal.getAsInteger(0, IVal)) { - D.Diag(diag::err_drv_defsym_invalid_symval) << SVal; - break; - } - CmdArgs.push_back(Value.data()); - TakeNextArg = true; + if (A->getNumValues() != 2) { + D.Diag(diag::err_drv_defsym_invalid_format) << Value; + break; + } + const char *S = A->getValue(1); + auto Pair = StringRef(S).split('='); + auto Sym = Pair.first; + auto SVal = Pair.second; + + if (Sym.empty() || SVal.empty()) { + D.Diag(diag::err_drv_defsym_invalid_format) << S; + break; + } + int64_t IVal; + if (SVal.getAsInteger(0, IVal)) { + D.Diag(diag::err_drv_defsym_invalid_symval) << SVal; + break; + } + CmdArgs.push_back(Value.data()); + TakeNextArg = true; } else if (Value == "-fdebug-compilation-dir") { CmdArgs.push_back("-fdebug-compilation-dir"); TakeNextArg = true; @@ -3198,13 +3200,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, options::OPT_fstrict_float_cast_overflow, false)) CmdArgs.push_back("-fno-strict-float-cast-overflow"); - if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) + if (Args.hasArg(options::OPT_fcx_limited_range)) CmdArgs.push_back("-fcx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules)) + if (Args.hasArg(options::OPT_fcx_fortran_rules)) CmdArgs.push_back("-fcx-fortran-rules"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) + if (Args.hasArg(options::OPT_fno_cx_limited_range)) CmdArgs.push_back("-fno-cx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules)) + if (Args.hasArg(options::OPT_fno_cx_fortran_rules)) CmdArgs.push_back("-fno-cx-fortran-rules"); } @@ -3331,7 +3333,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, // --param ssp-buffer-size= for (const Arg *A : Args.filtered(options::OPT__param)) { StringRef Str(A->getValue()); - if (Str.startswith("ssp-buffer-size=")) { + if (Str.starts_with("ssp-buffer-size=")) { if (StackProtectorLevel) { CmdArgs.push_back("-stack-protector-buffer-size"); // FIXME: Verify the argument is a valid integer. @@ -5615,6 +5617,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_auto_import); } + if (Args.hasFlag(options::OPT_fms_volatile, options::OPT_fno_ms_volatile, + Triple.isX86() && D.IsCLMode())) + CmdArgs.push_back("-fms-volatile"); + // Non-PIC code defaults to -fdirect-access-external-data while PIC code // defaults to -fno-direct-access-external-data. Pass the option if different // from the default. @@ -5882,7 +5888,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, StringRef Val = A->getValue(); if (Triple.isX86() && Triple.isOSBinFormatELF()) { if (Val != "all" && Val != "labels" && Val != "none" && - !Val.startswith("list=")) + !Val.starts_with("list=")) D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); else @@ -7947,18 +7953,6 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back("-P"); } - unsigned VolatileOptionID; - if (getToolChain().getTriple().isX86()) - VolatileOptionID = options::OPT__SLASH_volatile_ms; - else - VolatileOptionID = options::OPT__SLASH_volatile_iso; - - if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group)) - VolatileOptionID = A->getOption().getID(); - - if (VolatileOptionID == options::OPT__SLASH_volatile_ms) - CmdArgs.push_back("-fms-volatile"); - if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_, options::OPT__SLASH_Zc_dllexportInlines, false)) { @@ -8390,14 +8384,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, continue; auto &JArgs = J.getArguments(); for (unsigned I = 0; I < JArgs.size(); ++I) { - if (StringRef(JArgs[I]).startswith("-object-file-name=") && + if (StringRef(JArgs[I]).starts_with("-object-file-name=") && Output.isFilename()) { - ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I); - addDebugObjectName(Args, NewArgs, DebugCompilationDir, - Output.getFilename()); - NewArgs.append(JArgs.begin() + I + 1, JArgs.end()); - J.replaceArguments(NewArgs); - break; + ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I); + addDebugObjectName(Args, NewArgs, DebugCompilationDir, + Output.getFilename()); + NewArgs.append(JArgs.begin() + I + 1, JArgs.end()); + J.replaceArguments(NewArgs); + break; } } } @@ -8661,7 +8655,7 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, getTargetFeatures(TC->getDriver(), TC->getTriple(), TCArgs, Features, false); llvm::copy_if(Features, std::back_inserter(FeatureArgs), - [](StringRef Arg) { return !Arg.startswith("-target"); }); + [](StringRef Arg) { return !Arg.starts_with("-target"); }); if (TC->getTriple().isAMDGPU()) { for (StringRef Feature : llvm::split(Arch.split(':').second, ':')) { diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 31e7d68161ff1b224dfa4b49433d82242b02794d..2340191ca97d9876bcdc9c979939b40f0c66d754 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -303,7 +303,7 @@ void tools::handleTargetFeaturesGroup(const Driver &D, A->claim(); // Skip over "-m". - assert(Name.startswith("m") && "Invalid feature name."); + assert(Name.starts_with("m") && "Invalid feature name."); Name = Name.substr(1); auto Proc = getCPUName(D, Args, Triple); @@ -317,7 +317,7 @@ void tools::handleTargetFeaturesGroup(const Driver &D, continue; } - bool IsNegative = Name.startswith("no-"); + bool IsNegative = Name.starts_with("no-"); if (IsNegative) Name = Name.substr(3); @@ -1116,66 +1116,112 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, return true; } +/// Determines if --whole-archive is active in the list of arguments. +static bool isWholeArchivePresent(const ArgList &Args) { + bool WholeArchiveActive = false; + for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) { + if (Arg) { + for (StringRef ArgValue : Arg->getValues()) { + if (ArgValue == "--whole-archive") + WholeArchiveActive = true; + if (ArgValue == "--no-whole-archive") + WholeArchiveActive = false; + } + } + } + + return WholeArchiveActive; +} + +/// Determine if driver is invoked to create a shared object library (-static) +static bool isSharedLinkage(const ArgList &Args) { + return Args.hasArg(options::OPT_shared); +} + +/// Determine if driver is invoked to create a static object library (-shared) +static bool isStaticLinkage(const ArgList &Args) { + return Args.hasArg(options::OPT_static); +} + +/// Add Fortran runtime libs for MSVC +static void addFortranRuntimeLibsMSVC(const ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) { + unsigned RTOptionID = options::OPT__SLASH_MT; + if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { + RTOptionID = llvm::StringSwitch(rtl->getValue()) + .Case("static", options::OPT__SLASH_MT) + .Case("static_dbg", options::OPT__SLASH_MTd) + .Case("dll", options::OPT__SLASH_MD) + .Case("dll_dbg", options::OPT__SLASH_MDd) + .Default(options::OPT__SLASH_MT); + } + switch (RTOptionID) { + case options::OPT__SLASH_MT: + CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib"); + break; + case options::OPT__SLASH_MTd: + CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib"); + break; + case options::OPT__SLASH_MD: + CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib"); + break; + case options::OPT__SLASH_MDd: + CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib"); + break; + } +} + +// Add FortranMain runtime lib +static void addFortranMain(const ToolChain &TC, const ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) { + // 0. Shared-library linkage + // If we are attempting to link a library, we should not add + // -lFortran_main.a to the link line, as the `main` symbol is not + // required for a library and should also be provided by one of + // the translation units of the code that this shared library + // will be linked against eventually. + if (isSharedLinkage(Args) || isStaticLinkage(Args)) { + return; + } + + // 1. MSVC + if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { + addFortranRuntimeLibsMSVC(Args, CmdArgs); + return; + } + + // 2. GNU and similar + // The --whole-archive option needs to be part of the link line to make + // sure that the main() function from Fortran_main.a is pulled in by the + // linker. However, it shouldn't be used if it's already active. + // TODO: Find an equivalent of `--whole-archive` for Darwin and AIX. + if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX() && + !TC.getTriple().isOSAIX()) { + CmdArgs.push_back("--whole-archive"); + CmdArgs.push_back("-lFortran_main"); + CmdArgs.push_back("--no-whole-archive"); + return; + } + + CmdArgs.push_back("-lFortran_main"); +} + +/// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { - // These are handled earlier on Windows by telling the frontend driver to add - // the correct libraries to link against as dependents in the object file. - - // if -fno-fortran-main has been passed, skip linking Fortran_main.a - bool LinkFortranMain = !Args.hasArg(options::OPT_no_fortran_main); + // 1. Link FortranMain + // FortranMain depends on FortranRuntime, so needs to be listed first. If + // -fno-fortran-main has been passed, skip linking Fortran_main.a + if (!Args.hasArg(options::OPT_no_fortran_main)) + addFortranMain(TC, Args, CmdArgs); + + // 2. Link FortranRuntime and FortranDecimal + // These are handled earlier on Windows by telling the frontend driver to + // add the correct libraries to link against as dependents in the object + // file. if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) { - if (LinkFortranMain) { - // The --whole-archive option needs to be part of the link line to - // make sure that the main() function from Fortran_main.a is pulled - // in by the linker. Determine if --whole-archive is active when - // flang will try to link Fortran_main.a. If it is, don't add the - // --whole-archive flag to the link line. If it's not, add a proper - // --whole-archive/--no-whole-archive bracket to the link line. - bool WholeArchiveActive = false; - for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) - if (Arg) - for (StringRef ArgValue : Arg->getValues()) { - if (ArgValue == "--whole-archive") - WholeArchiveActive = true; - if (ArgValue == "--no-whole-archive") - WholeArchiveActive = false; - } - - if (!WholeArchiveActive) - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back("-lFortran_main"); - if (!WholeArchiveActive) - CmdArgs.push_back("--no-whole-archive"); - } - // Perform regular linkage of the remaining runtime libraries. CmdArgs.push_back("-lFortranRuntime"); CmdArgs.push_back("-lFortranDecimal"); - } else { - if (LinkFortranMain) { - unsigned RTOptionID = options::OPT__SLASH_MT; - if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { - RTOptionID = llvm::StringSwitch(rtl->getValue()) - .Case("static", options::OPT__SLASH_MT) - .Case("static_dbg", options::OPT__SLASH_MTd) - .Case("dll", options::OPT__SLASH_MD) - .Case("dll_dbg", options::OPT__SLASH_MDd) - .Default(options::OPT__SLASH_MT); - } - switch (RTOptionID) { - case options::OPT__SLASH_MT: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib"); - break; - case options::OPT__SLASH_MTd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib"); - break; - case options::OPT__SLASH_MD: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib"); - break; - case options::OPT__SLASH_MDd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib"); - break; - } - } } } @@ -1292,28 +1338,28 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args); // Collect shared runtimes. if (SanArgs.needsSharedRt()) { - if (SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsAsanRt()) { SharedRuntimes.push_back("asan"); if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid()) HelperStaticRuntimes.push_back("asan-preinit"); } - if (SanArgs.needsMemProfRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsMemProfRt()) { SharedRuntimes.push_back("memprof"); if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid()) HelperStaticRuntimes.push_back("memprof-preinit"); } - if (SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsUbsanRt()) { if (SanArgs.requiresMinimalRuntime()) SharedRuntimes.push_back("ubsan_minimal"); else SharedRuntimes.push_back("ubsan_standalone"); } - if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsScudoRt()) { SharedRuntimes.push_back("scudo_standalone"); } - if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes()) + if (SanArgs.needsTsanRt()) SharedRuntimes.push_back("tsan"); - if (SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsHwasanRt()) { if (SanArgs.needsHwasanAliasesRt()) SharedRuntimes.push_back("hwasan_aliases"); else @@ -1324,7 +1370,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, } // The stats_client library is also statically linked into DSOs. - if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes()) + if (SanArgs.needsStatsRt()) StaticRuntimes.push_back("stats_client"); // Always link the static runtime regardless of DSO or executable. @@ -1340,20 +1386,19 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, // Each static runtime that has a DSO counterpart above is excluded below, // but runtimes that exist only as static are not affected by needsSharedRt. - if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt()) { StaticRuntimes.push_back("asan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("asan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt() && - SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) { StaticRuntimes.push_back("memprof"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("memprof_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt()) { if (SanArgs.needsHwasanAliasesRt()) { StaticRuntimes.push_back("hwasan_aliases"); if (SanArgs.linkCXXRuntimes()) @@ -1364,22 +1409,21 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("hwasan_cxx"); } } - if (SanArgs.needsDfsanRt() && SanArgs.linkRuntimes()) + if (SanArgs.needsDfsanRt()) StaticRuntimes.push_back("dfsan"); - if (SanArgs.needsLsanRt() && SanArgs.linkRuntimes()) + if (SanArgs.needsLsanRt()) StaticRuntimes.push_back("lsan"); - if (SanArgs.needsMsanRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsMsanRt()) { StaticRuntimes.push_back("msan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("msan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt() && - SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt()) { StaticRuntimes.push_back("tsan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("tsan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("ubsan_minimal"); } else { @@ -1388,24 +1432,24 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("ubsan_standalone_cxx"); } } - if (SanArgs.needsSafeStackRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsSafeStackRt()) { NonWholeStaticRuntimes.push_back("safestack"); RequiredSymbols.push_back("__safestack_init"); } - if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes())) { - if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes()) + if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt())) { + if (SanArgs.needsCfiRt()) StaticRuntimes.push_back("cfi"); - if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsCfiDiagRt()) { StaticRuntimes.push_back("cfi_diag"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("ubsan_standalone_cxx"); } } - if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes()) { + if (SanArgs.needsStatsRt()) { NonWholeStaticRuntimes.push_back("stats"); RequiredSymbols.push_back("__sanitizer_stats_register"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt()) { StaticRuntimes.push_back("scudo_standalone"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("scudo_standalone_cxx"); @@ -1416,13 +1460,15 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, // C runtime, etc). Returns true if sanitizer system deps need to be linked in. bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { + const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args); SmallVector SharedRuntimes, StaticRuntimes, NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols; - collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes, - NonWholeStaticRuntimes, HelperStaticRuntimes, - RequiredSymbols); + if (SanArgs.linkRuntimes()) { + collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes, + NonWholeStaticRuntimes, HelperStaticRuntimes, + RequiredSymbols); + } - const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args); // Inject libfuzzer dependencies. if (SanArgs.needsFuzzer() && SanArgs.linkRuntimes() && !Args.hasArg(options::OPT_shared)) { @@ -2336,20 +2382,19 @@ static void GetSDLFromOffloadArchive( llvm::Triple Triple(D.getTargetTriple()); bool IsMSVC = Triple.isWindowsMSVCEnvironment(); auto Ext = IsMSVC ? ".lib" : ".a"; - if (!Lib.startswith(":") && !Lib.startswith("-l")) { + if (!Lib.starts_with(":") && !Lib.starts_with("-l")) { if (llvm::sys::fs::exists(Lib)) { ArchiveOfBundles = Lib; FoundAOB = true; } } else { - if (Lib.startswith("-l")) - Lib = Lib.drop_front(2); + Lib.consume_front("-l"); for (auto LPath : LibraryPaths) { ArchiveOfBundles.clear(); - auto LibFile = - (Lib.startswith(":") ? Lib.drop_front() - : IsMSVC ? Lib + Ext : "lib" + Lib + Ext) - .str(); + auto LibFile = (Lib.starts_with(":") ? Lib.drop_front() + : IsMSVC ? Lib + Ext + : "lib" + Lib + Ext) + .str(); for (auto Prefix : {"/libdevice/", "/"}) { auto AOB = Twine(LPath + Prefix + LibFile).str(); if (llvm::sys::fs::exists(AOB)) { diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index ef1e77974c1eaaf79f707bfc22c565024f3b5862..f7a208575cb0cf8d617ab3da73d917285af5462e 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -238,7 +238,7 @@ CudaInstallationDetector::CudaInstallationDetector( // Process all bitcode filenames that look like // libdevice.compute_XX.YY.bc const StringRef LibDeviceName = "libdevice."; - if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc"))) + if (!(FileName.starts_with(LibDeviceName) && FileName.ends_with(".bc"))) continue; StringRef GpuArch = FileName.slice( LibDeviceName.size(), FileName.find('.', LibDeviceName.size())); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 692b3a3f285d744afc868a622ea7dc0aa1559de6..65846cace461e3eedf6a8c18ed53fd6f516f366d 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1010,13 +1010,13 @@ static const char *ArmMachOArchNameCPU(StringRef CPU) { // FIXME: Make sure this MachO triple mangling is really necessary. // ARMv5* normalises to ARMv5. - if (Arch.startswith("armv5")) + if (Arch.starts_with("armv5")) Arch = Arch.substr(0, 5); // ARMv6*, except ARMv6M, normalises to ARMv6. - else if (Arch.startswith("armv6") && !Arch.endswith("6m")) + else if (Arch.starts_with("armv6") && !Arch.ends_with("6m")) Arch = Arch.substr(0, 5); // ARMv7A normalises to ARMv7. - else if (Arch.endswith("v7a")) + else if (Arch.ends_with("v7a")) Arch = Arch.substr(0, 5); return Arch.data(); } @@ -1319,8 +1319,8 @@ StringRef Darwin::getSDKName(StringRef isysroot) { auto EndSDK = llvm::sys::path::rend(isysroot); for (auto IT = BeginSDK; IT != EndSDK; ++IT) { StringRef SDK = *IT; - if (SDK.endswith(".sdk")) - return SDK.slice(0, SDK.size() - 4); + if (SDK.ends_with(".sdk")) + return SDK.slice(0, SDK.size() - 4); } return ""; } @@ -1959,22 +1959,23 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args, auto CreatePlatformFromSDKName = [&](StringRef SDK) -> std::optional { - if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) + if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator")) return DarwinPlatform::createFromSDK( Darwin::IPhoneOS, Version, - /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); - else if (SDK.startswith("MacOSX")) + /*IsSimulator=*/SDK.starts_with("iPhoneSimulator")); + else if (SDK.starts_with("MacOSX")) return DarwinPlatform::createFromSDK(Darwin::MacOS, getSystemOrSDKMacOSVersion(Version)); - else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) + else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator")) return DarwinPlatform::createFromSDK( Darwin::WatchOS, Version, - /*IsSimulator=*/SDK.startswith("WatchSimulator")); - else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) + /*IsSimulator=*/SDK.starts_with("WatchSimulator")); + else if (SDK.starts_with("AppleTVOS") || + SDK.starts_with("AppleTVSimulator")) return DarwinPlatform::createFromSDK( Darwin::TvOS, Version, - /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); - else if (SDK.startswith("DriverKit")) + /*IsSimulator=*/SDK.starts_with("AppleTVSimulator")); + else if (SDK.starts_with("DriverKit")) return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version); return std::nullopt; }; @@ -2339,8 +2340,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { if (SDK.size() > 0) { size_t StartVer = SDK.find_first_of("0123456789"); StringRef SDKName = SDK.slice(0, StartVer); - if (!SDKName.startswith(getPlatformFamily()) && - !dropSDKNamePrefix(SDKName).startswith(getPlatformFamily())) + if (!SDKName.starts_with(getPlatformFamily()) && + !dropSDKNamePrefix(SDKName).starts_with(getPlatformFamily())) getDriver().Diag(diag::warn_incompatible_sysroot) << SDKName << getPlatformFamily(); } diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 502b9f17a06c52ff06434f206489f817f81dfcc4..41eaad3bbad0a37f1d191fc71facbc183286314a 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -182,7 +182,7 @@ void Flang::AddAArch64TargetArgs(const ArgList &Args, Val.equals("256+") || Val.equals("512+") || Val.equals("1024+") || Val.equals("2048+")) { unsigned Bits = 0; - if (Val.endswith("+")) + if (Val.ends_with("+")) Val = Val.substr(0, Val.size() - 1); else { [[maybe_unused]] bool Invalid = Val.getAsInteger(10, Bits); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index b875991844ffff5240cdb2195a77bf74945dca5e..a610a94a39a2b4b965f2b11f12a94c644310dec0 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -30,6 +30,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Path.h" +#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/TargetParser/TargetParser.h" #include @@ -1084,7 +1085,7 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags, .FilterOut(NonExistent) .setIncludeDirsCallback([](const Multilib &M) { std::vector Dirs({"/include"}); - if (StringRef(M.includeSuffix()).startswith("/uclibc")) + if (StringRef(M.includeSuffix()).starts_with("/uclibc")) Dirs.push_back( "/../../../../mips-linux-gnu/libc/uclibc/usr/include"); else @@ -1288,7 +1289,7 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags, .FilterOut(NonExistent) .setIncludeDirsCallback([](const Multilib &M) { std::vector Dirs({"/include"}); - if (StringRef(M.includeSuffix()).startswith("/uclibc")) + if (StringRef(M.includeSuffix()).starts_with("/uclibc")) Dirs.push_back("/../../../../sysroot/uclibc/usr/include"); else Dirs.push_back("/../../../../sysroot/usr/include"); @@ -1715,6 +1716,125 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple, Result.Multilibs = CSKYMultilibs; } +/// Extend the multi-lib re-use selection mechanism for RISC-V. +/// This function will try to re-use multi-lib if they are compatible. +/// Definition of compatible: +/// - ABI must be the same. +/// - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im +/// is a subset of march=rv32imc. +/// - march that contains atomic extension can't reuse multi-lib that +/// doesn't have atomic, vice versa. e.g. multi-lib=march=rv32im and +/// march=rv32ima are not compatible, because software and hardware +/// atomic operation can't work together correctly. +static bool +selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch, + const Multilib::flags_list &Flags, + llvm::SmallVectorImpl &SelectedMultilibs) { + // Try to find the perfect matching multi-lib first. + if (RISCVMultilibSet.select(Flags, SelectedMultilibs)) + return true; + + Multilib::flags_list NewFlags; + std::vector NewMultilibs; + + llvm::Expected> ParseResult = + llvm::RISCVISAInfo::parseArchString( + Arch, /*EnableExperimentalExtension=*/true, + /*ExperimentalExtensionVersionCheck=*/false); + // Ignore any error here, we assume it will be handled in another place. + if (llvm::errorToBool(ParseResult.takeError())) + return false; + + auto &ISAInfo = *ParseResult; + + addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags); + addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags); + + // Collect all flags except march=* + for (StringRef Flag : Flags) { + if (Flag.starts_with("!march=") || Flag.starts_with("-march=")) + continue; + + NewFlags.push_back(Flag.str()); + } + + llvm::StringSet<> AllArchExts; + // Reconstruct multi-lib list, and break march option into separated + // extension. e.g. march=rv32im -> +i +m + for (const auto &M : RISCVMultilibSet) { + bool Skip = false; + + MultilibBuilder NewMultilib = + MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix()); + for (StringRef Flag : M.flags()) { + // Add back all flags except -march. + if (!Flag.consume_front("-march=")) { + NewMultilib.flag(Flag); + continue; + } + + // Break down -march into individual extension. + llvm::Expected> MLConfigParseResult = + llvm::RISCVISAInfo::parseArchString( + Flag, /*EnableExperimentalExtension=*/true, + /*ExperimentalExtensionVersionCheck=*/false); + // Ignore any error here, we assume it will handled in another place. + if (llvm::errorToBool(MLConfigParseResult.takeError())) { + // We might get a parsing error if rv32e in the list, we could just skip + // that and process the rest of multi-lib configs. + Skip = true; + continue; + } + auto &MLConfigISAInfo = *MLConfigParseResult; + + const llvm::RISCVISAInfo::OrderedExtensionMap &MLConfigArchExts = + MLConfigISAInfo->getExtensions(); + for (auto MLConfigArchExt : MLConfigArchExts) { + auto ExtName = MLConfigArchExt.first; + NewMultilib.flag(Twine("-", ExtName).str()); + + if (AllArchExts.insert(ExtName).second) { + addMultilibFlag(ISAInfo->hasExtension(ExtName), + Twine("-", ExtName).str(), NewFlags); + } + } + + // Check the XLEN explicitly. + if (MLConfigISAInfo->getXLen() == 32) { + NewMultilib.flag("-m32"); + NewMultilib.flag("-m64", /*Disallow*/ true); + } else { + NewMultilib.flag("-m32", /*Disallow*/ true); + NewMultilib.flag("-m64"); + } + + // Atomic extension must be explicitly checked, soft and hard atomic + // operation never co-work correctly. + if (!MLConfigISAInfo->hasExtension("a")) + NewMultilib.flag("-a", /*Disallow*/ true); + } + + if (Skip) + continue; + + NewMultilibs.emplace_back(NewMultilib); + } + + // Build an internal used only multi-lib list, used for checking any + // compatible multi-lib. + MultilibSet NewRISCVMultilibs = + MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet(); + + if (NewRISCVMultilibs.select(NewFlags, SelectedMultilibs)) + for (const Multilib &NewSelectedM : SelectedMultilibs) + for (const auto &M : RISCVMultilibSet) + // Look up the corresponding multi-lib entry in original multi-lib set. + if (M.gccSuffix() == NewSelectedM.gccSuffix()) + return true; + + return false; +} + static void findRISCVBareMetalMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, @@ -1766,7 +1886,8 @@ static void findRISCVBareMetalMultilibs(const Driver &D, } } - if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs)) + if (selectRISCVMultilib(RISCVMultilibs, MArch, Flags, + Result.SelectedMultilibs)) Result.Multilibs = RISCVMultilibs; } @@ -3055,7 +3176,7 @@ void Generic_GCC::AddMultilibPaths(const Driver &D, // the cross. Note that GCC does include some of these directories in some // configurations but this seems somewhere between questionable and simply // a bug. - if (StringRef(LibPath).startswith(SysRoot)) + if (StringRef(LibPath).starts_with(SysRoot)) addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); } } diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index d0ff7d0c1310da565c02b95097d706264e73fb16..6a2a105bee32ef3e183559c0a9b4ae7771e8483e 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -54,11 +54,11 @@ static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args, auto makeFeature = [&Args](Twine T, bool Enable) -> StringRef { const std::string &S = T.str(); StringRef Opt(S); - if (Opt.endswith("=")) + if (Opt.ends_with("=")) Opt = Opt.drop_back(1); - if (Opt.startswith("mno-")) + if (Opt.starts_with("mno-")) Opt = Opt.drop_front(4); - else if (Opt.startswith("m")) + else if (Opt.starts_with("m")) Opt = Opt.drop_front(1); return Args.MakeArgString(Twine(Enable ? "+" : "-") + Twine(Opt)); }; @@ -801,7 +801,7 @@ StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) { CpuArg = A; StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU(); - if (CPU.startswith("hexagon")) + if (CPU.starts_with("hexagon")) return CPU.substr(sizeof("hexagon") - 1); return CPU; } diff --git a/clang/lib/Driver/ToolChains/Hurd.cpp b/clang/lib/Driver/ToolChains/Hurd.cpp index 2dfc90ef37f75d0e93e1ad77ffa514eac39e9732..7a4c2bb7ede1d5f1a9ba25ba93e7c6becdc599c5 100644 --- a/clang/lib/Driver/ToolChains/Hurd.cpp +++ b/clang/lib/Driver/ToolChains/Hurd.cpp @@ -92,7 +92,7 @@ Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // those searched. // FIXME: It's not clear whether we should use the driver's installed // directory ('Dir' below) or the ResourceDir. - if (StringRef(D.Dir).startswith(SysRoot)) { + if (StringRef(D.Dir).starts_with(SysRoot)) { addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths); addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths); } @@ -110,7 +110,7 @@ Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // searched. // FIXME: It's not clear whether we should use the driver's installed // directory ('Dir' below) or the ResourceDir. - if (StringRef(D.Dir).startswith(SysRoot)) + if (StringRef(D.Dir).starts_with(SysRoot)) addPathIfExists(D, D.Dir + "/../lib", Paths); addPathIfExists(D, SysRoot + "/lib", Paths); diff --git a/clang/lib/Driver/ToolChains/MSP430.cpp b/clang/lib/Driver/ToolChains/MSP430.cpp index b28d5e45706c9d6d7a382e951634e91f8ff7acec..8dc23521f400a09fb6dd288ff364ed332a4ef8d0 100644 --- a/clang/lib/Driver/ToolChains/MSP430.cpp +++ b/clang/lib/Driver/ToolChains/MSP430.cpp @@ -166,7 +166,7 @@ void MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs, return; const StringRef MCU = MCUArg->getValue(); - if (MCU.startswith("msp430i")) { + if (MCU.starts_with("msp430i")) { // 'i' should be in lower case as it's defined in TI MSP430-GCC headers CC1Args.push_back(DriverArgs.MakeArgString( "-D__MSP430i" + MCU.drop_front(7).upper() + "__")); diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 6d925555b7bb4b2d462ef91ab5eb0f0974ab1a0c..8e1e95173836ffe2c3c97fc0b916c7cfa163d584 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -302,7 +302,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (A.getOption().matches(options::OPT_l)) { StringRef Lib = A.getValue(); const char *LinkLibArg; - if (Lib.endswith(".lib")) + if (Lib.ends_with(".lib")) LinkLibArg = Args.MakeArgString(Lib); else LinkLibArg = Args.MakeArgString(Lib + ".lib"); diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index 5d7f8675daf8d28c35d62bfd3d9091ba8e0beaf6..65512f16357d044d4cbfcda328983bf24b50fe68 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -86,9 +86,9 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args, CmdArgs.push_back("-lmoldname"); CmdArgs.push_back("-lmingwex"); for (auto Lib : Args.getAllArgValues(options::OPT_l)) - if (StringRef(Lib).startswith("msvcr") || - StringRef(Lib).startswith("ucrt") || - StringRef(Lib).startswith("crtdll")) + if (StringRef(Lib).starts_with("msvcr") || + StringRef(Lib).starts_with("ucrt") || + StringRef(Lib).starts_with("crtdll")) return; CmdArgs.push_back("-lmsvcrt"); } diff --git a/clang/lib/Driver/ToolChains/PPCLinux.cpp b/clang/lib/Driver/ToolChains/PPCLinux.cpp index bdbecaef60405c24369f7f143cbf6b8776928583..0ed0f91ad166c0b1af2d7272a5ac515ce3e0d668 100644 --- a/clang/lib/Driver/ToolChains/PPCLinux.cpp +++ b/clang/lib/Driver/ToolChains/PPCLinux.cpp @@ -31,10 +31,10 @@ static bool GlibcSupportsFloat128(const std::string &Linker) { // Since glibc 2.34, the installed .so file is not symlink anymore. But we can // still safely assume it's newer than 2.32. - if (LinkerName.startswith("ld64.so")) + if (LinkerName.starts_with("ld64.so")) return true; - if (!LinkerName.startswith("ld-2.")) + if (!LinkerName.starts_with("ld-2.")) return false; unsigned Minor = (LinkerName[5] - '0') * 10 + (LinkerName[6] - '0'); if (Minor < 32) diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 485730da7df1f8cd4c8016a66edb061cc65a449c..200ac46aa534099aa28339515e9e9858c062b877 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -295,13 +295,12 @@ static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) { switch (Triple.getArch()) { case llvm::Triple::x86: case llvm::Triple::sparc: + default: break; case llvm::Triple::x86_64: return "/amd64"; case llvm::Triple::sparcv9: return "/sparcv9"; - default: - llvm_unreachable("Unsupported architecture"); } return ""; } @@ -328,7 +327,7 @@ Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, // If we are currently running Clang inside of the requested system root, // add its parent library path to those searched. - if (StringRef(D.Dir).startswith(D.SysRoot)) + if (StringRef(D.Dir).starts_with(D.SysRoot)) addPathIfExists(D, D.Dir + "/../lib", Paths); addPathIfExists(D, D.SysRoot + "/usr/lib" + LibSuffix, Paths); diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index f131b6cf3baff9d7ccfc2782d3ddfe6ea9b17b57..57f4600727ec89db91c8938bbdc19f3da845fdbc 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -328,7 +328,7 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { StringRef Opt = A->getValue(0); - if (Opt.startswith("-emscripten-cxx-exceptions-allowed")) { + if (Opt.starts_with("-emscripten-cxx-exceptions-allowed")) { // '-mllvm -emscripten-cxx-exceptions-allowed' should be used with // '-mllvm -enable-emscripten-cxx-exceptions' bool EmEHArgExists = false; @@ -355,7 +355,7 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, } } - if (Opt.startswith("-wasm-enable-sjlj")) { + if (Opt.starts_with("-wasm-enable-sjlj")) { // '-mllvm -wasm-enable-sjlj' is not compatible with // '-mno-exception-handling' if (DriverArgs.hasFlag(options::OPT_mno_exception_handing, diff --git a/clang/lib/Edit/Commit.cpp b/clang/lib/Edit/Commit.cpp index 7c5aea6e5069a504b5c9c0f30ef9ae866932b530..6e785e866666f161b4a2a656cbfec1564147d5a8 100644 --- a/clang/lib/Edit/Commit.cpp +++ b/clang/lib/Edit/Commit.cpp @@ -334,7 +334,7 @@ bool Commit::canReplaceText(SourceLocation loc, StringRef text, return false; Len = text.size(); - return file.substr(Offs.getOffset()).startswith(text); + return file.substr(Offs.getOffset()).starts_with(text); } bool Commit::isAtStartOfMacroExpansion(SourceLocation loc, diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index adb34eba49703064b2748f3c8f444ecd71b04c1e..d5bf553e241240daf72277bb374b6af7cecd1381 100644 --- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -697,7 +697,7 @@ static bool getLiteralInfo(SourceRange literalRange, struct Suff { static bool has(StringRef suff, StringRef &text) { - if (text.endswith(suff)) { + if (text.ends_with(suff)) { text = text.substr(0, text.size()-suff.size()); return true; } @@ -739,9 +739,9 @@ static bool getLiteralInfo(SourceRange literalRange, Info.F = UpperF ? "F" : "f"; Info.Hex = Info.Octal = false; - if (text.startswith("0x")) + if (text.starts_with("0x")) Info.Hex = true; - else if (!isFloat && !isIntZero && text.startswith("0")) + else if (!isFloat && !isIntZero && text.starts_with("0")) Info.Octal = true; SourceLocation B = literalRange.getBegin(); diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index fe282dfb19e8aa7fa9bf6ff43ee2c18b309864a7..fd62d841197d9f08e02ab3c4d906e703e19ec289 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -105,10 +105,10 @@ std::optional getRelativeIncludeName(const CompilerInstance &CI, // Special case Apple .sdk folders since the search path is typically a // symlink like `iPhoneSimulator14.5.sdk` while the file is instead // located in `iPhoneSimulator.sdk` (the real folder). - if (NI->endswith(".sdk") && DI->endswith(".sdk")) { + if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) { StringRef NBasename = path::stem(*NI); StringRef DBasename = path::stem(*DI); - if (DBasename.startswith(NBasename)) + if (DBasename.starts_with(NBasename)) continue; } diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index d9675b0c94de3962fa185b87f9819bb2d844b268..53b22297ee0ea19e4e23b504baa42ea899b6bf8c 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -743,7 +743,7 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const { // Filter out symbols prefixed with an underscored as they are understood to // be symbols clients should not use. - if (Record.Name.startswith("_")) + if (Record.Name.starts_with("_")) return true; return false; diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 954eeb9a6f24fc4a73a98d4d3290a274fc379cbb..473908e8fee3b3da6557e77d3c2dc6be8931e209 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -55,7 +55,7 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment, })); for (StringRef KnownPrefix : KnownPrefixes) { - if (Comment.startswith(KnownPrefix)) { + if (Comment.starts_with(KnownPrefix)) { const auto PrefixLength = Comment.find_first_not_of(' ', KnownPrefix.size()); return Comment.substr(0, PrefixLength); @@ -220,8 +220,8 @@ bool switchesFormatting(const FormatToken &Token) { assert((Token.is(TT_BlockComment) || Token.is(TT_LineComment)) && "formatting regions are switched by comment tokens"); StringRef Content = Token.TokenText.substr(2).ltrim(); - return Content.startswith("clang-format on") || - Content.startswith("clang-format off"); + return Content.starts_with("clang-format on") || + Content.starts_with("clang-format off"); } unsigned @@ -271,7 +271,7 @@ BreakableStringLiteral::BreakableStringLiteral( : BreakableToken(Tok, InPPDirective, Encoding, Style), StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix), UnbreakableTailLength(UnbreakableTailLength) { - assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix)); + assert(Tok.TokenText.starts_with(Prefix) && Tok.TokenText.ends_with(Postfix)); Line = Tok.TokenText.substr( Prefix.size(), Tok.TokenText.size() - Prefix.size() - Postfix.size()); } @@ -454,7 +454,7 @@ static bool mayReflowContent(StringRef Content) { bool hasSpecialMeaningPrefix = false; for (StringRef Prefix : {"@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* "}) { - if (Content.startswith(Prefix)) { + if (Content.starts_with(Prefix)) { hasSpecialMeaningPrefix = true; break; } @@ -471,7 +471,7 @@ static bool mayReflowContent(StringRef Content) { // characters and either the first or second character must be // non-punctuation. return Content.size() >= 2 && !hasSpecialMeaningPrefix && - !Content.endswith("\\") && + !Content.ends_with("\\") && // Note that this is UTF-8 safe, since if isPunctuation(Content[0]) is // true, then the first code point must be 1 byte long. (!isPunctuation(Content[0]) || !isPunctuation(Content[1])); @@ -488,7 +488,7 @@ BreakableBlockComment::BreakableBlockComment( "block comment section must start with a block comment"); StringRef TokenText(Tok.TokenText); - assert(TokenText.startswith("/*") && TokenText.endswith("*/")); + assert(TokenText.starts_with("/*") && TokenText.ends_with("*/")); TokenText.substr(2, TokenText.size() - 4) .split(Lines, UseCRLF ? "\r\n" : "\n"); @@ -511,7 +511,7 @@ BreakableBlockComment::BreakableBlockComment( // /* // ** blah blah blah // */ - if (Lines.size() >= 2 && Content[1].startswith("**") && + if (Lines.size() >= 2 && Content[1].starts_with("**") && static_cast(ContentColumn[1]) == StartColumn) { DecorationColumn = StartColumn; } @@ -531,10 +531,10 @@ BreakableBlockComment::BreakableBlockComment( // If the last line is empty, the closing "*/" will have a star. if (Text.empty()) break; - } else if (!Text.empty() && Decoration.startswith(Text)) { + } else if (!Text.empty() && Decoration.starts_with(Text)) { continue; } - while (!Text.startswith(Decoration)) + while (!Text.starts_with(Decoration)) Decoration = Decoration.drop_back(1); } @@ -562,13 +562,13 @@ BreakableBlockComment::BreakableBlockComment( // The last line excludes the star if LastLineNeedsDecoration is false. // For all other lines, adjust the line to exclude the star and // (optionally) the first whitespace. - unsigned DecorationSize = Decoration.startswith(Content[i]) + unsigned DecorationSize = Decoration.starts_with(Content[i]) ? Content[i].size() : Decoration.size(); if (DecorationSize) ContentColumn[i] = DecorationColumn + DecorationSize; Content[i] = Content[i].substr(DecorationSize); - if (!Decoration.startswith(Content[i])) { + if (!Decoration.starts_with(Content[i])) { IndentAtLineBreak = std::min(IndentAtLineBreak, std::max(0, ContentColumn[i])); } @@ -577,10 +577,10 @@ BreakableBlockComment::BreakableBlockComment( // Detect a multiline jsdoc comment and set DelimitersOnNewline in that case. if (Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) { - if ((Lines[0] == "*" || Lines[0].startswith("* ")) && Lines.size() > 1) { + if ((Lines[0] == "*" || Lines[0].starts_with("* ")) && Lines.size() > 1) { // This is a multiline jsdoc comment. DelimitersOnNewline = true; - } else if (Lines[0].startswith("* ") && Lines.size() == 1) { + } else if (Lines[0].starts_with("* ") && Lines.size() == 1) { // Detect a long single-line comment, like: // /** long long long */ // Below, '2' is the width of '*/'. @@ -612,7 +612,7 @@ BreakableToken::Split BreakableBlockComment::getSplit( return Split(StringRef::npos, 0); return getCommentSplit(Content[LineIndex].substr(TailOffset), ContentStartColumn, ColumnLimit, Style.TabWidth, - Encoding, Style, Decoration.endswith("*")); + Encoding, Style, Decoration.ends_with("*")); } void BreakableBlockComment::adjustWhitespace(unsigned LineIndex, @@ -623,7 +623,7 @@ void BreakableBlockComment::adjustWhitespace(unsigned LineIndex, // trimming the trailing whitespace. The backslash will be re-added later when // inserting a line break. size_t EndOfPreviousLine = Lines[LineIndex - 1].size(); - if (InPPDirective && Lines[LineIndex - 1].endswith("\\")) + if (InPPDirective && Lines[LineIndex - 1].ends_with("\\")) --EndOfPreviousLine; // Calculate the end of the non-whitespace text in the previous line. @@ -672,7 +672,7 @@ unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex, // We never need a decoration when breaking just the trailing "*/" postfix. bool HasRemainingText = Offset < Content[LineIndex].size(); if (!HasRemainingText) { - bool HasDecoration = Lines[LineIndex].ltrim().startswith(Decoration); + bool HasDecoration = Lines[LineIndex].ltrim().starts_with(Decoration); if (HasDecoration) LineLength -= Decoration.size(); } @@ -700,7 +700,7 @@ unsigned BreakableBlockComment::getContentIndent(unsigned LineIndex) const { // /** line 0 */ // is "* line 0", so we need to skip over the decoration in that case. StringRef ContentWithNoDecoration = Content[LineIndex]; - if (LineIndex == 0 && ContentWithNoDecoration.startswith("*")) + if (LineIndex == 0 && ContentWithNoDecoration.starts_with("*")) ContentWithNoDecoration = ContentWithNoDecoration.substr(1).ltrim(Blanks); StringRef FirstWord = ContentWithNoDecoration.substr( 0, ContentWithNoDecoration.find_first_of(Blanks)); @@ -853,7 +853,7 @@ bool BreakableBlockComment::mayReflow( // Content[LineIndex] may exclude the indent after the '*' decoration. In that // case, we compute the start of the comment pragma manually. StringRef IndentContent = Content[LineIndex]; - if (Lines[LineIndex].ltrim(Blanks).startswith("*")) + if (Lines[LineIndex].ltrim(Blanks).starts_with("*")) IndentContent = Lines[LineIndex].ltrim(Blanks).substr(1); return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) && mayReflowContent(Content[LineIndex]) && !Tok.Finalized && @@ -876,7 +876,7 @@ BreakableLineCommentSection::BreakableLineCommentSection( CurrentTok = CurrentTok->Next) { LastLineTok = LineTok; StringRef TokenText(CurrentTok->TokenText); - assert((TokenText.startswith("//") || TokenText.startswith("#")) && + assert((TokenText.starts_with("//") || TokenText.starts_with("#")) && "unsupported line comment prefix, '//' and '#' are supported"); size_t FirstLineIndex = Lines.size(); TokenText.split(Lines, "\n"); @@ -913,7 +913,7 @@ BreakableLineCommentSection::BreakableLineCommentSection( // ######### // # section // ######### - if (FirstCommentChar == '#' && !TokenText.startswith("#")) + if (FirstCommentChar == '#' && !TokenText.starts_with("#")) return false; return FirstCommentChar == '\\' || isPunctuation(FirstCommentChar) || isHorizontalWhitespace(FirstCommentChar); @@ -1152,7 +1152,7 @@ bool BreakableLineCommentSection::mayReflow( // Line comments have the indent as part of the prefix, so we need to // recompute the start of the line. StringRef IndentContent = Content[LineIndex]; - if (Lines[LineIndex].startswith("//")) + if (Lines[LineIndex].starts_with("//")) IndentContent = Lines[LineIndex].substr(2); // FIXME: Decide whether we want to reflow non-regular indents: // Currently, we only reflow when the OriginalPrefix[LineIndex] matches the diff --git a/clang/lib/Format/CMakeLists.txt b/clang/lib/Format/CMakeLists.txt index 015ec7c0cc84e3f68b18c41a4cbd602d09f75e18..84a3c136f650a85062bc3f40e36e4be83cca7a02 100644 --- a/clang/lib/Format/CMakeLists.txt +++ b/clang/lib/Format/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_library(clangFormat IntegerLiteralSeparatorFixer.cpp MacroCallReconstructor.cpp MacroExpander.cpp + MatchFilePath.cpp NamespaceEndCommentsFixer.cpp ObjCPropertyAttributeOrderFixer.cpp QualifierAlignmentFixer.cpp diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 9e4e939503dfe4a0b5dd501e14353cdb4133c664..102504182c4505b0a624574da504298b23041743 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -161,7 +161,7 @@ static bool opensProtoMessageField(const FormatToken &LessTok, // string. For example, the delimiter of R"deli(cont)deli" is deli. static std::optional getRawStringDelimiter(StringRef TokenText) { if (TokenText.size() < 5 // The smallest raw string possible is 'R"()"'. - || !TokenText.startswith("R\"") || !TokenText.endswith("\"")) { + || !TokenText.starts_with("R\"") || !TokenText.ends_with("\"")) { return std::nullopt; } @@ -177,7 +177,7 @@ static std::optional getRawStringDelimiter(StringRef TokenText) { size_t RParenPos = TokenText.size() - Delimiter.size() - 2; if (TokenText[RParenPos] != ')') return std::nullopt; - if (!TokenText.substr(RParenPos + 1).startswith(Delimiter)) + if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter)) return std::nullopt; return Delimiter; } @@ -398,7 +398,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && - Style.isCpp() && + State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() && // FIXME: This is a temporary workaround for the case where clang-format // sets BreakBeforeParameter to avoid bin packing and this creates a // completely unnecessary line break after a template type that isn't @@ -583,17 +583,15 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { return true; } - // If the return type spans multiple lines, wrap before the function name. - if (((Current.is(TT_FunctionDeclarationName) && - !State.Line->ReturnTypeWrapped && - // Don't break before a C# function when no break after return type. - (!Style.isCSharp() || - Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) && - // Don't always break between a JavaScript `function` and the function - // name. - !Style.isJavaScript()) || - (Current.is(tok::kw_operator) && Previous.isNot(tok::coloncolon))) && - Previous.isNot(tok::kw_template) && CurrentState.BreakBeforeParameter) { + if (Current.is(TT_FunctionDeclarationName) && + !State.Line->ReturnTypeWrapped && + // Don't break before a C# function when no break after return type. + (!Style.isCSharp() || + Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) && + // Don't always break between a JavaScript `function` and the function + // name. + !Style.isJavaScript() && Previous.isNot(tok::kw_template) && + CurrentState.BreakBeforeParameter) { return true; } @@ -608,7 +606,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { if (Current.is(tok::lessless) && ((Previous.is(tok::identifier) && Previous.TokenText == "endl") || - (Previous.Tok.isLiteral() && (Previous.TokenText.endswith("\\n\"") || + (Previous.Tok.isLiteral() && (Previous.TokenText.ends_with("\\n\"") || Previous.TokenText == "\'\\n\'")))) { return true; } @@ -2293,12 +2291,13 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current, if (Style.isVerilog() || Style.Language == FormatStyle::LK_Java || Style.isJavaScript() || Style.isCSharp()) { BreakableStringLiteralUsingOperators::QuoteStyleType QuoteStyle; - if (Style.isJavaScript() && Text.startswith("'") && Text.endswith("'")) { + if (Style.isJavaScript() && Text.starts_with("'") && + Text.ends_with("'")) { QuoteStyle = BreakableStringLiteralUsingOperators::SingleQuotes; - } else if (Style.isCSharp() && Text.startswith("@\"") && - Text.endswith("\"")) { + } else if (Style.isCSharp() && Text.starts_with("@\"") && + Text.ends_with("\"")) { QuoteStyle = BreakableStringLiteralUsingOperators::AtDoubleQuotes; - } else if (Text.startswith("\"") && Text.endswith("\"")) { + } else if (Text.starts_with("\"") && Text.ends_with("\"")) { QuoteStyle = BreakableStringLiteralUsingOperators::DoubleQuotes; } else { return nullptr; @@ -2315,12 +2314,14 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current, // FIXME: Store Prefix and Suffix (or PrefixLength and SuffixLength to // reduce the overhead) for each FormatToken, which is a string, so that we // don't run multiple checks here on the hot path. - if ((Text.endswith(Postfix = "\"") && - (Text.startswith(Prefix = "@\"") || Text.startswith(Prefix = "\"") || - Text.startswith(Prefix = "u\"") || Text.startswith(Prefix = "U\"") || - Text.startswith(Prefix = "u8\"") || - Text.startswith(Prefix = "L\""))) || - (Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")"))) { + if ((Text.ends_with(Postfix = "\"") && + (Text.starts_with(Prefix = "@\"") || Text.starts_with(Prefix = "\"") || + Text.starts_with(Prefix = "u\"") || + Text.starts_with(Prefix = "U\"") || + Text.starts_with(Prefix = "u8\"") || + Text.starts_with(Prefix = "L\""))) || + (Text.starts_with(Prefix = "_T(\"") && + Text.ends_with(Postfix = "\")"))) { return std::make_unique( Current, StartColumn, Prefix, Postfix, UnbreakableTailLength, State.Line->InPPDirective, Encoding, Style); @@ -2342,7 +2343,7 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current, bool RegularComments = [&]() { for (const FormatToken *T = &Current; T && T->is(TT_LineComment); T = T->Next) { - if (!(T->TokenText.startswith("//") || T->TokenText.startswith("#"))) + if (!(T->TokenText.starts_with("//") || T->TokenText.starts_with("#"))) return false; } return true; @@ -2754,7 +2755,7 @@ bool ContinuationIndenter::nextIsMultilineString(const LineState &State) { // We never consider raw string literals "multiline" for the purpose of // AlwaysBreakBeforeMultilineStrings implementation as they are special-cased // (see TokenAnnotator::mustBreakBefore(). - if (Current.TokenText.startswith("R\"")) + if (Current.TokenText.starts_with("R\"")) return false; if (Current.IsMultiline) return true; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 8feee7457fc31b76a09f9c9ebd9a9104db281404..f798d555bf9929c247ff77233c78c9c0b8abbd83 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1315,7 +1315,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) { Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; Expanded.BraceWrapping.AfterExternBlock = true; - Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.SplitEmptyFunction = true; Expanded.BraceWrapping.SplitEmptyRecord = false; break; @@ -1335,7 +1334,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) { Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; Expanded.BraceWrapping.AfterExternBlock = true; - Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.BeforeCatch = true; Expanded.BraceWrapping.BeforeElse = true; Expanded.BraceWrapping.BeforeLambdaBody = true; @@ -1350,7 +1348,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) { Expanded.BraceWrapping.AfterObjCDeclaration = true; Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterExternBlock = true; - Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.BeforeCatch = true; Expanded.BraceWrapping.BeforeElse = true; Expanded.BraceWrapping.BeforeLambdaBody = true; @@ -1375,7 +1372,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) { /*SplitEmptyFunction=*/true, /*SplitEmptyRecord=*/true, /*SplitEmptyNamespace=*/true}; - Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; break; case FormatStyle::BS_WebKit: Expanded.BraceWrapping.AfterFunction = true; @@ -1702,6 +1698,9 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { /*BasedOnStyle=*/"google", }, }; + GoogleStyle.AttributeMacros.push_back("GUARDED_BY"); + GoogleStyle.AttributeMacros.push_back("ABSL_GUARDED_BY"); + GoogleStyle.SpacesBeforeTrailingComments = 2; GoogleStyle.Standard = FormatStyle::LS_Auto; @@ -1909,7 +1908,6 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) { Style.BraceWrapping.AfterObjCDeclaration = true; Style.BraceWrapping.AfterStruct = true; Style.BraceWrapping.AfterExternBlock = true; - Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Style.BraceWrapping.BeforeCatch = true; Style.BraceWrapping.BeforeElse = true; Style.BraceWrapping.BeforeWhile = false; @@ -2346,9 +2344,9 @@ private: // NB: testing for not starting with a double quote to avoid // breaking `template strings`. (Style.JavaScriptQuotes == FormatStyle::JSQS_Single && - !Input.startswith("\"")) || + !Input.starts_with("\"")) || (Style.JavaScriptQuotes == FormatStyle::JSQS_Double && - !Input.startswith("\'"))) { + !Input.starts_with("\'"))) { continue; } @@ -2932,7 +2930,7 @@ private: }; for (auto *Line : AnnotatedLines) { - if (Line->First && (Line->First->TokenText.startswith("#") || + if (Line->First && (Line->First->TokenText.starts_with("#") || Line->First->TokenText == "__pragma" || Line->First->TokenText == "_Pragma")) { continue; @@ -3217,7 +3215,7 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Regroup); - bool MergeWithNextLine = Trimmed.endswith("\\"); + bool MergeWithNextLine = Trimmed.ends_with("\\"); if (!FormattingOff && !MergeWithNextLine) { if (tooling::HeaderIncludes::IncludeRegex.match(Line, &Matches)) { StringRef IncludeName = Matches[2]; @@ -3243,7 +3241,7 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces, Cursor); IncludesInBlock.clear(); - if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers. + if (Trimmed.starts_with("#pragma hdrstop")) // Precompiled headers. FirstIncludeBlock = true; else FirstIncludeBlock = false; @@ -3271,7 +3269,7 @@ static unsigned findJavaImportGroup(const FormatStyle &Style, unsigned LongestMatchLength = 0; for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) { const std::string &GroupPrefix = Style.JavaImportGroups[I]; - if (ImportIdentifier.startswith(GroupPrefix) && + if (ImportIdentifier.starts_with(GroupPrefix) && GroupPrefix.length() > LongestMatchLength) { LongestMatchIndex = I; LongestMatchLength = GroupPrefix.length(); @@ -3426,7 +3424,7 @@ bool isMpegTS(StringRef Code) { return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47; } -bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); } +bool isLikelyXml(StringRef Code) { return Code.ltrim().starts_with("<"); } tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, ArrayRef Ranges, @@ -3538,7 +3536,7 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, for (const auto &Header : HeadersToDelete) { tooling::Replacements Replaces = - Includes.remove(Header.trim("\"<>"), Header.startswith("<")); + Includes.remove(Header.trim("\"<>"), Header.starts_with("<")); for (const auto &R : Replaces) { auto Err = Result.add(R); if (Err) { @@ -3560,7 +3558,7 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, (void)Matched; auto IncludeName = Matches[2]; auto Replace = - Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<"), + Includes.insert(IncludeName.trim("\"<>"), IncludeName.starts_with("<"), tooling::IncludeDirective::Include); if (Replace) { auto Err = Result.add(*Replace); @@ -3882,14 +3880,14 @@ const char *StyleOptionHelpDescription = " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { - if (FileName.endswith(".java")) + if (FileName.ends_with(".java")) return FormatStyle::LK_Java; if (FileName.ends_with_insensitive(".js") || FileName.ends_with_insensitive(".mjs") || FileName.ends_with_insensitive(".ts")) { return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript. } - if (FileName.endswith(".m") || FileName.endswith(".mm")) + if (FileName.ends_with(".m") || FileName.ends_with(".mm")) return FormatStyle::LK_ObjC; if (FileName.ends_with_insensitive(".proto") || FileName.ends_with_insensitive(".protodevel")) { @@ -3963,7 +3961,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, llvm::SmallVector, 1> ChildFormatTextToApply; - if (StyleName.startswith("{")) { + if (StyleName.starts_with("{")) { // Parse YAML/JSON style from the command line. StringRef Source = ""; if (std::error_code ec = @@ -4123,7 +4121,7 @@ static bool isClangFormatOnOff(StringRef Comment, bool On) { static const char ClangFormatOff[] = "// clang-format off"; const unsigned Size = (On ? sizeof ClangFormatOn : sizeof ClangFormatOff) - 1; - return Comment.startswith(On ? ClangFormatOn : ClangFormatOff) && + return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) && (Comment.size() == Size || Comment[Size] == ':'); } diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 14a3c21ba44eaee9c77da15e37cd914a32518c43..3f9664f8f78a3e4d3329b04cb53ff5d776bc1cd8 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -667,7 +667,7 @@ public: /// Returns whether \p Tok is ([{ or an opening < of a template or in /// protos. bool opensScope() const { - if (is(TT_TemplateString) && TokenText.endswith("${")) + if (is(TT_TemplateString) && TokenText.ends_with("${")) return true; if (is(TT_DictLiteral) && is(tok::less)) return true; @@ -677,7 +677,7 @@ public: /// Returns whether \p Tok is )]} or a closing > of a template or in /// protos. bool closesScope() const { - if (is(TT_TemplateString) && TokenText.startswith("}")) + if (is(TT_TemplateString) && TokenText.starts_with("}")) return true; if (is(TT_DictLiteral) && is(tok::greater)) return true; @@ -743,9 +743,9 @@ public: if (isNot(tok::string_literal)) return false; StringRef Content = TokenText; - if (Content.startswith("\"") || Content.startswith("'")) + if (Content.starts_with("\"") || Content.starts_with("'")) Content = Content.drop_front(1); - if (Content.endswith("\"") || Content.endswith("'")) + if (Content.ends_with("\"") || Content.ends_with("'")) Content = Content.drop_back(1); Content = Content.trim(); return Content.size() > 1 && @@ -1823,7 +1823,7 @@ private: }; inline bool isLineComment(const FormatToken &FormatTok) { - return FormatTok.is(tok::comment) && !FormatTok.TokenText.startswith("/*"); + return FormatTok.is(tok::comment) && !FormatTok.TokenText.starts_with("/*"); } // Checks if \p FormatTok is a line comment that continues the line comment diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index e4e32e2671df57d925ab5d18af39419f7b0660eb..61430282c6f88ca09e7e2b14c25103d66a9469c2 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -711,12 +711,12 @@ void FormatTokenLexer::handleCSharpVerbatimAndInterpolatedStrings() { bool Verbatim = false; bool Interpolated = false; - if (TokenText.startswith(R"($@")") || TokenText.startswith(R"(@$")")) { + if (TokenText.starts_with(R"($@")") || TokenText.starts_with(R"(@$")")) { Verbatim = true; Interpolated = true; - } else if (TokenText.startswith(R"(@")")) { + } else if (TokenText.starts_with(R"(@")")) { Verbatim = true; - } else if (TokenText.startswith(R"($")")) { + } else if (TokenText.starts_with(R"($")")) { Interpolated = true; } @@ -1110,7 +1110,7 @@ FormatToken *FormatTokenLexer::getNextToken() { // the comment token at the backslash, and resets the lexer to restart behind // the backslash. if ((Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) && - FormatTok->is(tok::comment) && FormatTok->TokenText.startswith("//")) { + FormatTok->is(tok::comment) && FormatTok->TokenText.starts_with("//")) { size_t BackslashPos = FormatTok->TokenText.find('\\'); while (BackslashPos != StringRef::npos) { if (BackslashPos + 1 < FormatTok->TokenText.size() && diff --git a/clang/lib/Format/MatchFilePath.cpp b/clang/lib/Format/MatchFilePath.cpp new file mode 100644 index 0000000000000000000000000000000000000000..062b334dcdd8fd24698713bd653c32d1964edea0 --- /dev/null +++ b/clang/lib/Format/MatchFilePath.cpp @@ -0,0 +1,122 @@ +//===--- MatchFilePath.cpp - Match file path with pattern -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements the functionality of matching a file path name to +/// a pattern, similar to the POSIX fnmatch() function. +/// +//===----------------------------------------------------------------------===// + +#include "MatchFilePath.h" + +using namespace llvm; + +namespace clang { +namespace format { + +// Check whether `FilePath` matches `Pattern` based on POSIX 2.13.1, 2.13.2, and +// Rule 1 of 2.13.3. +bool matchFilePath(StringRef Pattern, StringRef FilePath) { + assert(!Pattern.empty()); + assert(!FilePath.empty()); + + // No match if `Pattern` ends with a non-meta character not equal to the last + // character of `FilePath`. + if (const auto C = Pattern.back(); !strchr("?*]", C) && C != FilePath.back()) + return false; + + constexpr auto Separator = '/'; + const auto EOP = Pattern.size(); // End of `Pattern`. + const auto End = FilePath.size(); // End of `FilePath`. + unsigned I = 0; // Index to `Pattern`. + + for (unsigned J = 0; J < End; ++J) { + if (I == EOP) + return false; + + switch (const auto F = FilePath[J]; Pattern[I]) { + case '\\': + if (++I == EOP || F != Pattern[I]) + return false; + break; + case '?': + if (F == Separator) + return false; + break; + case '*': { + while (++I < EOP && Pattern[I] == '*') { // Skip consecutive stars. + } + const auto K = FilePath.find(Separator, J); // Index of next `Separator`. + const bool NoMoreSeparatorsInFilePath = K == StringRef::npos; + if (I == EOP) // `Pattern` ends with a star. + return NoMoreSeparatorsInFilePath; + // `Pattern` ends with a lone backslash. + if (Pattern[I] == '\\' && ++I == EOP) + return false; + // The star is followed by a (possibly escaped) `Separator`. + if (Pattern[I] == Separator) { + if (NoMoreSeparatorsInFilePath) + return false; + J = K; // Skip to next `Separator` in `FilePath`. + break; + } + // Recurse. + for (auto Pat = Pattern.substr(I); J < End && FilePath[J] != Separator; + ++J) { + if (matchFilePath(Pat, FilePath.substr(J))) + return true; + } + return false; + } + case '[': + // Skip e.g. `[!]`. + if (I + 3 < EOP || (I + 3 == EOP && Pattern[I + 1] != '!')) { + // Skip unpaired `[`, brackets containing slashes, and `[]`. + if (const auto K = Pattern.find_first_of("]/", I + 1); + K != StringRef::npos && Pattern[K] == ']' && K > I + 1) { + if (F == Separator) + return false; + ++I; // After the `[`. + bool Negated = false; + if (Pattern[I] == '!') { + Negated = true; + ++I; // After the `!`. + } + bool Match = false; + do { + if (I + 2 < K && Pattern[I + 1] == '-') { + Match = Pattern[I] <= F && F <= Pattern[I + 2]; + I += 3; // After the range, e.g. `A-Z`. + } else { + Match = F == Pattern[I++]; + } + } while (!Match && I < K); + if (Negated ? Match : !Match) + return false; + I = K + 1; // After the `]`. + continue; + } + } + [[fallthrough]]; // Match `[` literally. + default: + if (F != Pattern[I]) + return false; + } + + ++I; + } + + // Match trailing stars with null strings. + while (I < EOP && Pattern[I] == '*') + ++I; + + return I == EOP; +} + +} // namespace format +} // namespace clang diff --git a/clang/lib/Format/MatchFilePath.h b/clang/lib/Format/MatchFilePath.h new file mode 100644 index 0000000000000000000000000000000000000000..482dab7c748e519255b5c131323ccad53ebd9643 --- /dev/null +++ b/clang/lib/Format/MatchFilePath.h @@ -0,0 +1,22 @@ +//===--- MatchFilePath.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_FORMAT_MATCHFILEPATH_H +#define LLVM_CLANG_LIB_FORMAT_MATCHFILEPATH_H + +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace format { + +bool matchFilePath(llvm::StringRef Pattern, llvm::StringRef FilePath); + +} // end namespace format +} // end namespace clang + +#endif diff --git a/clang/lib/Format/SortJavaScriptImports.cpp b/clang/lib/Format/SortJavaScriptImports.cpp index 8c6722e915344fb233b78bbde6f85ee2ca4c074d..1a6a1b19e7022a080460b1dfd0a0cd152673a4bf 100644 --- a/clang/lib/Format/SortJavaScriptImports.cpp +++ b/clang/lib/Format/SortJavaScriptImports.cpp @@ -468,10 +468,10 @@ private: // URL = TokenText without the quotes. Reference.URL = Current->TokenText.substr(1, Current->TokenText.size() - 2); - if (Reference.URL.startswith("..")) { + if (Reference.URL.starts_with("..")) { Reference.Category = JsModuleReference::ReferenceCategory::RELATIVE_PARENT; - } else if (Reference.URL.startswith(".")) { + } else if (Reference.URL.starts_with(".")) { Reference.Category = JsModuleReference::ReferenceCategory::RELATIVE; } else { Reference.Category = JsModuleReference::ReferenceCategory::ABSOLUTE; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index eaccb5881ca30f5e381f20b1e17d36894041985d..3ac3aa3c5e3a2258f20408bd4bed5d46602ab4a9 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -164,6 +164,10 @@ private: TT_OverloadedOperatorLParen))) { return false; } + if (Previous.Previous->is(tok::kw_operator) && + CurrentToken->is(tok::l_paren)) { + return false; + } } FormatToken *Left = CurrentToken->Previous; @@ -1307,7 +1311,7 @@ private: if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma, tok::star, tok::arrow, tok::amp, tok::ampamp) || // User defined literal. - Previous->TokenText.startswith("\"\"")) { + Previous->TokenText.starts_with("\"\"")) { Previous->setType(TT_OverloadedOperator); if (CurrentToken->isOneOf(tok::less, tok::greater)) break; @@ -1466,7 +1470,7 @@ private: // Mark tokens up to the trailing line comments as implicit string // literals. if (CurrentToken->isNot(tok::comment) && - !CurrentToken->TokenText.startswith("//")) { + !CurrentToken->TokenText.starts_with("//")) { CurrentToken->setType(TT_ImplicitStringLiteral); } next(); @@ -2077,8 +2081,8 @@ private: } Current.setType(TT_BinaryOperator); } else if (Current.is(tok::comment)) { - if (Current.TokenText.startswith("/*")) { - if (Current.TokenText.endswith("*/")) { + if (Current.TokenText.starts_with("/*")) { + if (Current.TokenText.ends_with("*/")) { Current.setType(TT_BlockComment); } else { // The lexer has for some reason determined a comment here. But we @@ -3399,7 +3403,8 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, continue; } if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() || - Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) { + Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis, + TT_TypeName)) { return true; } if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral()) @@ -3724,8 +3729,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, return 100; if (Left.is(TT_JsTypeColon)) return 35; - if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) || - (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) { + if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) || + (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) { return 100; } // Prefer breaking call chains (".foo") over empty "{}", "[]" or "()". @@ -4224,7 +4229,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, } if (Left.is(TT_BlockComment)) { // No whitespace in x(/*foo=*/1), except for JavaScript. - return Style.isJavaScript() || !Left.TokenText.endswith("=*/"); + return Style.isJavaScript() || !Left.TokenText.ends_with("=*/"); } // Space between template and attribute. @@ -4572,8 +4577,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Next && Next->is(TT_FatArrow)) return true; } - if ((Left.is(TT_TemplateString) && Left.TokenText.endswith("${")) || - (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) { + if ((Left.is(TT_TemplateString) && Left.TokenText.ends_with("${")) || + (Right.is(TT_TemplateString) && Right.TokenText.starts_with("}"))) { return false; } // In tagged template literals ("html`bar baz`"), there is no space between @@ -5212,7 +5217,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, Left.is(TT_InheritanceComma)) { return true; } - if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\"")) { + if (Right.is(tok::string_literal) && Right.TokenText.starts_with("R\"")) { // Multiline raw string literals are special wrt. line breaks. The author // has made a deliberate choice and might have aligned the contents of the // string literal accordingly. Thus, we try keep existing line breaks. diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 57126b8dfeac5de62da5b519c1ad0e0b3b5cdc62..684609747a5513f5e7807f334f71311302c34ff0 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1333,7 +1333,7 @@ bool UnwrappedLineParser::parseModuleImport() { // Mark tokens up to the trailing line comments as implicit string // literals. if (FormatTok->isNot(tok::comment) && - !FormatTok->TokenText.startswith("//")) { + !FormatTok->TokenText.starts_with("//")) { FormatTok->setFinalizedType(TT_ImplicitStringLiteral); } nextToken(); @@ -1371,7 +1371,7 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() { bool PreviousMustBeValue = mustBeJSIdentOrValue(Keywords, Previous); bool PreviousStartsTemplateExpr = - Previous->is(TT_TemplateString) && Previous->TokenText.endswith("${"); + Previous->is(TT_TemplateString) && Previous->TokenText.ends_with("${"); if (PreviousMustBeValue || Previous->is(tok::r_paren)) { // If the line contains an '@' sign, the previous token might be an // annotation, which can precede another identifier/value. @@ -1385,7 +1385,7 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() { return addUnwrappedLine(); bool NextMustBeValue = mustBeJSIdentOrValue(Keywords, Next); bool NextEndsTemplateExpr = - Next->is(TT_TemplateString) && Next->TokenText.startswith("}"); + Next->is(TT_TemplateString) && Next->TokenText.starts_with("}"); if (NextMustBeValue && !NextEndsTemplateExpr && !PreviousStartsTemplateExpr && (PreviousMustBeValue || Previous->isOneOf(tok::r_square, tok::r_paren, tok::plusplus, @@ -1650,8 +1650,10 @@ void UnwrappedLineParser::parseStructuralElement( return; } // In Verilog labels can be any expression, so we don't do them here. - if (!Style.isVerilog() && Tokens->peekNextToken()->is(tok::colon) && - !Line->MustBeDeclaration) { + // JS doesn't have macros, and within classes colons indicate fields, not + // labels. + if (!Style.isJavaScript() && !Style.isVerilog() && + Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) { nextToken(); Line->Tokens.begin()->Tok->MustBreakBefore = true; FormatTok->setFinalizedType(TT_GotoLabelColon); @@ -4459,8 +4461,8 @@ continuesLineCommentSection(const FormatToken &FormatTok, return false; StringRef IndentContent = FormatTok.TokenText; - if (FormatTok.TokenText.startswith("//") || - FormatTok.TokenText.startswith("/*")) { + if (FormatTok.TokenText.starts_with("//") || + FormatTok.TokenText.starts_with("/*")) { IndentContent = FormatTok.TokenText.substr(2); } if (CommentPragmasRegex.match(IndentContent)) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index b33bdad2ad81bad041c9ca791066ac347706d1e7..11f3f2c2d6425cce7f51ca5c79b28b6ac79646fd 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2829,7 +2829,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, "-interface-stub-version=ifs-v1" << ErrorMessage; ProgramAction = frontend::ParseSyntaxOnly; - } else if (!ArgStr.startswith("ifs-")) { + } else if (!ArgStr.starts_with("ifs-")) { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + "."; Diags.Report(diag::err_drv_invalid_value) @@ -4106,13 +4106,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, // Check the version number is valid: either 3.x (0 <= x <= 9) or // y or y.0 (4 <= y <= current version). - if (!VerParts.first.startswith("0") && - !VerParts.first.getAsInteger(10, Major) && - 3 <= Major && Major <= CLANG_VERSION_MAJOR && - (Major == 3 ? VerParts.second.size() == 1 && - !VerParts.second.getAsInteger(10, Minor) - : VerParts.first.size() == Ver.size() || - VerParts.second == "0")) { + if (!VerParts.first.starts_with("0") && + !VerParts.first.getAsInteger(10, Major) && 3 <= Major && + Major <= CLANG_VERSION_MAJOR && + (Major == 3 + ? VerParts.second.size() == 1 && + !VerParts.second.getAsInteger(10, Minor) + : VerParts.first.size() == Ver.size() || VerParts.second == "0")) { // Got a valid version number. if (Major == 3 && Minor <= 8) Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8); diff --git a/clang/lib/Frontend/DependencyGraph.cpp b/clang/lib/Frontend/DependencyGraph.cpp index 6aad04370f6e7ad27efff42769186eebf8a4be31..b471471f3528a7ff770bbf6f6f38c684d8e45e5f 100644 --- a/clang/lib/Frontend/DependencyGraph.cpp +++ b/clang/lib/Frontend/DependencyGraph.cpp @@ -110,8 +110,7 @@ void DependencyGraphCallback::OutputGraphFile() { writeNodeReference(OS, AllFiles[I]); OS << " [ shape=\"box\", label=\""; StringRef FileName = AllFiles[I].getName(); - if (FileName.startswith(SysRoot)) - FileName = FileName.substr(SysRoot.size()); + FileName.consume_front(SysRoot); OS << DOT::EscapeString(std::string(FileName)) << "\"];\n"; } diff --git a/clang/lib/Frontend/LayoutOverrideSource.cpp b/clang/lib/Frontend/LayoutOverrideSource.cpp index f474d4fe8fdcb85949129d9dc76eceb19ddc7760..a1866ec09c9d3d5252228a4952aa385cb29e9345 100644 --- a/clang/lib/Frontend/LayoutOverrideSource.cpp +++ b/clang/lib/Frontend/LayoutOverrideSource.cpp @@ -147,8 +147,7 @@ LayoutOverrideSource::LayoutOverrideSource(StringRef Filename) { // Skip over this offset, the following comma, and any spaces. LineStr = LineStr.substr(1); - while (!LineStr.empty() && isWhitespace(LineStr[0])) - LineStr = LineStr.substr(1); + LineStr = LineStr.drop_while(isWhitespace); } } @@ -163,8 +162,7 @@ LayoutOverrideSource::LayoutOverrideSource(StringRef Filename) { // Skip over this offset, the following comma, and any spaces. LineStr = LineStr.substr(1); - while (!LineStr.empty() && isWhitespace(LineStr[0])) - LineStr = LineStr.substr(1); + LineStr = LineStr.drop_while(isWhitespace); } continue; } @@ -180,8 +178,7 @@ LayoutOverrideSource::LayoutOverrideSource(StringRef Filename) { // Skip over this offset, the following comma, and any spaces. LineStr = LineStr.substr(1); - while (!LineStr.empty() && isWhitespace(LineStr[0])) - LineStr = LineStr.substr(1); + LineStr = LineStr.drop_while(isWhitespace); } } } diff --git a/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp b/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp index 2c3a253a67d5c930ed823f447af511573bb51919..b6b37461089e4860e5f46cf8ec2b78121f08a96d 100644 --- a/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -307,7 +307,7 @@ void InclusionRewriter::OutputContentUpTo(const MemoryBufferRef &FromFile, Rest = Rest.substr(Idx); } } - if (EnsureNewline && !TextToWrite.endswith(LocalEOL)) + if (EnsureNewline && !TextToWrite.ends_with(LocalEOL)) OS << MainEOL; WriteFrom = WriteTo; diff --git a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index ab8174f4f4db9216a21c912bec1346dfaee4af09..8a3d2286cd168c3b3f6310e89d8e34d9d68c21a0 100644 --- a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -226,10 +226,10 @@ public: P = C; while (P < End) { StringRef S(P, End - P); - if (S.startswith(OpenBrace)) { + if (S.starts_with(OpenBrace)) { ++Depth; P += OpenBrace.size(); - } else if (S.startswith(CloseBrace)) { + } else if (S.starts_with(CloseBrace)) { --Depth; if (Depth == 0) { PEnd = P + CloseBrace.size(); @@ -445,7 +445,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, // others. // Regex in initial directive token: -re - if (DToken.endswith("-re")) { + if (DToken.ends_with("-re")) { D.RegexKind = true; KindStr = "regex"; DToken = DToken.substr(0, DToken.size()-3); @@ -454,20 +454,19 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, // Type in initial directive token: -{error|warning|note|no-diagnostics} bool NoDiag = false; StringRef DType; - if (DToken.endswith(DType="-error")) + if (DToken.ends_with(DType = "-error")) D.DL = ED ? &ED->Errors : nullptr; - else if (DToken.endswith(DType="-warning")) + else if (DToken.ends_with(DType = "-warning")) D.DL = ED ? &ED->Warnings : nullptr; - else if (DToken.endswith(DType="-remark")) + else if (DToken.ends_with(DType = "-remark")) D.DL = ED ? &ED->Remarks : nullptr; - else if (DToken.endswith(DType="-note")) + else if (DToken.ends_with(DType = "-note")) D.DL = ED ? &ED->Notes : nullptr; - else if (DToken.endswith(DType="-no-diagnostics")) { + else if (DToken.ends_with(DType = "-no-diagnostics")) { NoDiag = true; if (D.RegexKind) continue; - } - else + } else continue; DToken = DToken.substr(0, DToken.size()-DType.size()); @@ -1145,8 +1144,7 @@ std::unique_ptr Directive::create(bool RegexKind, std::string RegexStr; StringRef S = Text; while (!S.empty()) { - if (S.startswith("{{")) { - S = S.drop_front(2); + if (S.consume_front("{{")) { size_t RegexMatchLength = S.find("}}"); assert(RegexMatchLength != StringRef::npos); // Append the regex, enclosed in parentheses. diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index fdd54c05eedf8250436b1bff46c66178846f5f91..735e4e4e3be89b7ed9cafe35ef1cb3cabebbf12d 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -139,6 +139,7 @@ set(webassembly_files set(x86_files # Intrinsics + adcintrin.h adxintrin.h ammintrin.h amxcomplexintrin.h @@ -387,6 +388,8 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD) clang_generate_header(-gen-arm-mve-header arm_mve.td arm_mve.h) # Generate arm_cde.h clang_generate_header(-gen-arm-cde-header arm_cde.td arm_cde.h) + # Generate arm_vector_types.h + clang_generate_header(-gen-arm-vector-type arm_neon.td arm_vector_types.h) # Add headers to target specific lists list(APPEND arm_common_generated_files @@ -403,6 +406,7 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD) "${CMAKE_CURRENT_BINARY_DIR}/arm_sve.h" "${CMAKE_CURRENT_BINARY_DIR}/arm_sme_draft_spec_subject_to_change.h" "${CMAKE_CURRENT_BINARY_DIR}/arm_bf16.h" + "${CMAKE_CURRENT_BINARY_DIR}/arm_vector_types.h" ) endif() if(RISCV IN_LIST LLVM_TARGETS_TO_BUILD) diff --git a/clang/lib/Headers/adcintrin.h b/clang/lib/Headers/adcintrin.h new file mode 100644 index 0000000000000000000000000000000000000000..0065a1b543f816b550dc27d9cabc243fffecf159 --- /dev/null +++ b/clang/lib/Headers/adcintrin.h @@ -0,0 +1,160 @@ +/*===---- adcintrin.h - ADC 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 __ADCINTRIN_H +#define __ADCINTRIN_H + +#if !defined(__i386__) && !defined(__x86_64__) +#error "This header is only meant to be used on x86 and x64 architecture" +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Use C++ inline semantics in C++, GNU inline for C mode. */ +#if defined(__cplusplus) +#define __INLINE __inline +#else +#define __INLINE static __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated +/// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory +/// at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +/// The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +/// A 32-bit unsigned addend. +/// \param __y +/// A 32-bit unsigned addend. +/// \param __p +/// Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry +/// flag \a __cf, and subtracts the result from unsigned 32-bit integer +/// \a __x. Stores the unsigned 32-bit difference in the memory at \a __p, +/// and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c SBB instruction. +/// +/// \param __cf +/// The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +/// The 32-bit unsigned minuend. +/// \param __y +/// The 32-bit unsigned subtrahend. +/// \param __p +/// Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated +/// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory +/// at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store64(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +/// The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +/// A 64-bit unsigned addend. +/// \param __y +/// A 64-bit unsigned addend. +/// \param __p +/// Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS +_addcarry_u64(unsigned char __cf, unsigned long long __x, + unsigned long long __y, unsigned long long *__p) { + return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p); +} + +/// Adds unsigned 64-bit integer \a __y to 0 or 1 as indicated by the carry +/// flag \a __cf, and subtracts the result from unsigned 64-bit integer +/// \a __x. Stores the unsigned 64-bit difference in the memory at \a __p, +/// and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store64(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +/// The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +/// The 64-bit unsigned minuend. +/// \param __y +/// The 64-bit unsigned subtrahend. +/// \param __p +/// Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS +_subborrow_u64(unsigned char __cf, unsigned long long __x, + unsigned long long __y, unsigned long long *__p) { + return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p); +} +#endif + +#if defined(__cplusplus) +} +#endif + +#undef __INLINE +#undef __DEFAULT_FN_ATTRS + +#endif /* __ADCINTRIN_H */ diff --git a/clang/lib/Headers/adxintrin.h b/clang/lib/Headers/adxintrin.h index 20f6211e567b30b1e4e562f737f5f620ae4db454..bc6a4caf35337ea8d86fddab29c91b2330acd80a 100644 --- a/clang/lib/Headers/adxintrin.h +++ b/clang/lib/Headers/adxintrin.h @@ -15,7 +15,8 @@ #define __ADXINTRIN_H /* Define the default attributes for the functions in this file. */ -#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("adx"))) /* Use C++ inline semantics in C++, GNU inline for C mode. */ #if defined(__cplusplus) @@ -53,10 +54,10 @@ extern "C" { /// \param __p /// Pointer to memory for storing the sum. /// \returns The 8-bit unsigned carry-out value. -__INLINE unsigned char - __attribute__((__always_inline__, __nodebug__, __target__("adx"))) - _addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y, - unsigned int *__p) { +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarryx_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); } @@ -84,137 +85,10 @@ __INLINE unsigned char /// \param __p /// Pointer to memory for storing the sum. /// \returns The 8-bit unsigned carry-out value. -__INLINE unsigned char - __attribute__((__always_inline__, __nodebug__, __target__("adx"))) - _addcarryx_u64(unsigned char __cf, unsigned long long __x, - unsigned long long __y, unsigned long long *__p) { - return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p); -} -#endif - -/* Intrinsics that are also available if __ADX__ is undefined. */ - -/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated -/// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory -/// at \a __p, and returns the 8-bit carry-out (carry flag). -/// -/// \code{.operation} -/// temp := (__cf == 0) ? 0 : 1 -/// Store32(__p, __x + __y + temp) -/// result := CF -/// \endcode -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c ADC instruction. -/// -/// \param __cf -/// The 8-bit unsigned carry flag; any non-zero value indicates carry. -/// \param __x -/// A 32-bit unsigned addend. -/// \param __y -/// A 32-bit unsigned addend. -/// \param __p -/// Pointer to memory for storing the sum. -/// \returns The 8-bit unsigned carry-out value. -__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, - unsigned int __x, - unsigned int __y, - unsigned int *__p) { - return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); -} - -#ifdef __x86_64__ -/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated -/// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory -/// at \a __p, and returns the 8-bit carry-out (carry flag). -/// -/// \code{.operation} -/// temp := (__cf == 0) ? 0 : 1 -/// Store64(__p, __x + __y + temp) -/// result := CF -/// \endcode -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c ADC instruction. -/// -/// \param __cf -/// The 8-bit unsigned carry flag; any non-zero value indicates carry. -/// \param __x -/// A 64-bit unsigned addend. -/// \param __y -/// A 64-bit unsigned addend. -/// \param __p -/// Pointer to memory for storing the sum. -/// \returns The 8-bit unsigned carry-out value. __INLINE unsigned char __DEFAULT_FN_ATTRS -_addcarry_u64(unsigned char __cf, unsigned long long __x, - unsigned long long __y, unsigned long long *__p) { - return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p); -} -#endif - -/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry -/// flag \a __cf, and subtracts the result from unsigned 32-bit integer -/// \a __x. Stores the unsigned 32-bit difference in the memory at \a __p, -/// and returns the 8-bit carry-out (carry or overflow flag). -/// -/// \code{.operation} -/// temp := (__cf == 0) ? 0 : 1 -/// Store32(__p, __x - (__y + temp)) -/// result := CF -/// \endcode -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c SBB instruction. -/// -/// \param __cf -/// The 8-bit unsigned carry flag; any non-zero value indicates carry. -/// \param __x -/// The 32-bit unsigned minuend. -/// \param __y -/// The 32-bit unsigned subtrahend. -/// \param __p -/// Pointer to memory for storing the difference. -/// \returns The 8-bit unsigned carry-out value. -__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, - unsigned int __x, - unsigned int __y, - unsigned int *__p) { - return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); -} - -#ifdef __x86_64__ -/// Adds unsigned 64-bit integer \a __y to 0 or 1 as indicated by the carry -/// flag \a __cf, and subtracts the result from unsigned 64-bit integer -/// \a __x. Stores the unsigned 64-bit difference in the memory at \a __p, -/// and returns the 8-bit carry-out (carry or overflow flag). -/// -/// \code{.operation} -/// temp := (__cf == 0) ? 0 : 1 -/// Store64(__p, __x - (__y + temp)) -/// result := CF -/// \endcode -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c ADC instruction. -/// -/// \param __cf -/// The 8-bit unsigned carry flag; any non-zero value indicates carry. -/// \param __x -/// The 64-bit unsigned minuend. -/// \param __y -/// The 64-bit unsigned subtrahend. -/// \param __p -/// Pointer to memory for storing the difference. -/// \returns The 8-bit unsigned carry-out value. -__INLINE unsigned char __DEFAULT_FN_ATTRS -_subborrow_u64(unsigned char __cf, unsigned long long __x, +_addcarryx_u64(unsigned char __cf, unsigned long long __x, unsigned long long __y, unsigned long long *__p) { - return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p); + return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p); } #endif @@ -222,6 +96,7 @@ _subborrow_u64(unsigned char __cf, unsigned long long __x, } #endif +#undef __INLINE #undef __DEFAULT_FN_ATTRS #endif /* __ADXINTRIN_H */ diff --git a/clang/lib/Headers/avx512bwintrin.h b/clang/lib/Headers/avx512bwintrin.h index 51dba5427b0fc0ab00f14774b3c3839d80424cb0..c854720de6a650b158cc87cadf2cf15d99617dcb 100644 --- a/clang/lib/Headers/avx512bwintrin.h +++ b/clang/lib/Headers/avx512bwintrin.h @@ -18,8 +18,9 @@ typedef unsigned int __mmask32; typedef unsigned long long __mmask64; /* Define the default attributes for the functions in this file. */ -#define __DEFAULT_FN_ATTRS512 __attribute__((__always_inline__, __nodebug__, __target__("avx512bw,evex512"), __min_vector_width__(512))) -#define __DEFAULT_FN_ATTRS64 __attribute__((__always_inline__, __nodebug__, __target__("avx512bw,evex512"))) +#define __DEFAULT_FN_ATTRS512 \ + __attribute__((__always_inline__, __nodebug__, \ + __target__("avx512bw,evex512"), __min_vector_width__(512))) #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, \ __target__("avx512bw,no-evex512"))) @@ -30,9 +31,7 @@ _knot_mask32(__mmask32 __M) return __builtin_ia32_knotsi(__M); } -static __inline __mmask64 __DEFAULT_FN_ATTRS64 -_knot_mask64(__mmask64 __M) -{ +static __inline __mmask64 __DEFAULT_FN_ATTRS _knot_mask64(__mmask64 __M) { return __builtin_ia32_knotdi(__M); } @@ -42,9 +41,8 @@ _kand_mask32(__mmask32 __A, __mmask32 __B) return (__mmask32)__builtin_ia32_kandsi((__mmask32)__A, (__mmask32)__B); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_kand_mask64(__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kand_mask64(__mmask64 __A, + __mmask64 __B) { return (__mmask64)__builtin_ia32_kanddi((__mmask64)__A, (__mmask64)__B); } @@ -54,9 +52,8 @@ _kandn_mask32(__mmask32 __A, __mmask32 __B) return (__mmask32)__builtin_ia32_kandnsi((__mmask32)__A, (__mmask32)__B); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_kandn_mask64(__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kandn_mask64(__mmask64 __A, + __mmask64 __B) { return (__mmask64)__builtin_ia32_kandndi((__mmask64)__A, (__mmask64)__B); } @@ -66,9 +63,8 @@ _kor_mask32(__mmask32 __A, __mmask32 __B) return (__mmask32)__builtin_ia32_korsi((__mmask32)__A, (__mmask32)__B); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_kor_mask64(__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kor_mask64(__mmask64 __A, + __mmask64 __B) { return (__mmask64)__builtin_ia32_kordi((__mmask64)__A, (__mmask64)__B); } @@ -78,9 +74,8 @@ _kxnor_mask32(__mmask32 __A, __mmask32 __B) return (__mmask32)__builtin_ia32_kxnorsi((__mmask32)__A, (__mmask32)__B); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_kxnor_mask64(__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kxnor_mask64(__mmask64 __A, + __mmask64 __B) { return (__mmask64)__builtin_ia32_kxnordi((__mmask64)__A, (__mmask64)__B); } @@ -90,9 +85,8 @@ _kxor_mask32(__mmask32 __A, __mmask32 __B) return (__mmask32)__builtin_ia32_kxorsi((__mmask32)__A, (__mmask32)__B); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_kxor_mask64(__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kxor_mask64(__mmask64 __A, + __mmask64 __B) { return (__mmask64)__builtin_ia32_kxordi((__mmask64)__A, (__mmask64)__B); } @@ -114,19 +108,17 @@ _kortest_mask32_u8(__mmask32 __A, __mmask32 __B, unsigned char *__C) { return (unsigned char)__builtin_ia32_kortestzsi(__A, __B); } -static __inline__ unsigned char __DEFAULT_FN_ATTRS64 -_kortestc_mask64_u8(__mmask64 __A, __mmask64 __B) -{ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_kortestc_mask64_u8(__mmask64 __A, __mmask64 __B) { return (unsigned char)__builtin_ia32_kortestcdi(__A, __B); } -static __inline__ unsigned char __DEFAULT_FN_ATTRS64 -_kortestz_mask64_u8(__mmask64 __A, __mmask64 __B) -{ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_kortestz_mask64_u8(__mmask64 __A, __mmask64 __B) { return (unsigned char)__builtin_ia32_kortestzdi(__A, __B); } -static __inline__ unsigned char __DEFAULT_FN_ATTRS64 +static __inline__ unsigned char __DEFAULT_FN_ATTRS _kortest_mask64_u8(__mmask64 __A, __mmask64 __B, unsigned char *__C) { *__C = (unsigned char)__builtin_ia32_kortestcdi(__A, __B); return (unsigned char)__builtin_ia32_kortestzdi(__A, __B); @@ -150,19 +142,17 @@ _ktest_mask32_u8(__mmask32 __A, __mmask32 __B, unsigned char *__C) { return (unsigned char)__builtin_ia32_ktestzsi(__A, __B); } -static __inline__ unsigned char __DEFAULT_FN_ATTRS64 -_ktestc_mask64_u8(__mmask64 __A, __mmask64 __B) -{ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_ktestc_mask64_u8(__mmask64 __A, __mmask64 __B) { return (unsigned char)__builtin_ia32_ktestcdi(__A, __B); } -static __inline__ unsigned char __DEFAULT_FN_ATTRS64 -_ktestz_mask64_u8(__mmask64 __A, __mmask64 __B) -{ +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_ktestz_mask64_u8(__mmask64 __A, __mmask64 __B) { return (unsigned char)__builtin_ia32_ktestzdi(__A, __B); } -static __inline__ unsigned char __DEFAULT_FN_ATTRS64 +static __inline__ unsigned char __DEFAULT_FN_ATTRS _ktest_mask64_u8(__mmask64 __A, __mmask64 __B, unsigned char *__C) { *__C = (unsigned char)__builtin_ia32_ktestcdi(__A, __B); return (unsigned char)__builtin_ia32_ktestzdi(__A, __B); @@ -174,9 +164,8 @@ _kadd_mask32(__mmask32 __A, __mmask32 __B) return (__mmask32)__builtin_ia32_kaddsi((__mmask32)__A, (__mmask32)__B); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_kadd_mask64(__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kadd_mask64(__mmask64 __A, + __mmask64 __B) { return (__mmask64)__builtin_ia32_kadddi((__mmask64)__A, (__mmask64)__B); } @@ -197,7 +186,7 @@ _cvtmask32_u32(__mmask32 __A) { return (unsigned int)__builtin_ia32_kmovd((__mmask32)__A); } -static __inline__ unsigned long long __DEFAULT_FN_ATTRS64 +static __inline__ unsigned long long __DEFAULT_FN_ATTRS _cvtmask64_u64(__mmask64 __A) { return (unsigned long long)__builtin_ia32_kmovq((__mmask64)__A); } @@ -207,7 +196,7 @@ _cvtu32_mask32(unsigned int __A) { return (__mmask32)__builtin_ia32_kmovd((__mmask32)__A); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _cvtu64_mask64(unsigned long long __A) { return (__mmask64)__builtin_ia32_kmovq((__mmask64)__A); } @@ -217,8 +206,7 @@ _load_mask32(__mmask32 *__A) { return (__mmask32)__builtin_ia32_kmovd(*(__mmask32 *)__A); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_load_mask64(__mmask64 *__A) { +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _load_mask64(__mmask64 *__A) { return (__mmask64)__builtin_ia32_kmovq(*(__mmask64 *)__A); } @@ -227,8 +215,8 @@ _store_mask32(__mmask32 *__A, __mmask32 __B) { *(__mmask32 *)__A = __builtin_ia32_kmovd((__mmask32)__B); } -static __inline__ void __DEFAULT_FN_ATTRS64 -_store_mask64(__mmask64 *__A, __mmask64 __B) { +static __inline__ void __DEFAULT_FN_ATTRS _store_mask64(__mmask64 *__A, + __mmask64 __B) { *(__mmask64 *)__A = __builtin_ia32_kmovq((__mmask64)__B); } @@ -1717,9 +1705,8 @@ _mm512_maskz_set1_epi8 (__mmask64 __M, char __A) (__v64qi) _mm512_setzero_si512()); } -static __inline__ __mmask64 __DEFAULT_FN_ATTRS64 -_mm512_kunpackd (__mmask64 __A, __mmask64 __B) -{ +static __inline__ __mmask64 __DEFAULT_FN_ATTRS _mm512_kunpackd(__mmask64 __A, + __mmask64 __B) { return (__mmask64) __builtin_ia32_kunpckdi ((__mmask64) __A, (__mmask64) __B); } diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index 9bfe2fcdabdb3a548bb619353bb454b3842b099f..0149a1cdea633b52d9a4782295a36f8075d603c9 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -580,9 +580,13 @@ _storebe_i64(void * __P, long long __D) { #include #endif -/* Some intrinsics inside adxintrin.h are available only on processors with ADX, - * whereas others are also available at all times. */ +/* Intrinsics inside adcintrin.h are available at all times. */ +#include + +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__ADX__) #include +#endif #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ defined(__RDSEED__) diff --git a/clang/lib/Headers/riscv_bitmanip.h b/clang/lib/Headers/riscv_bitmanip.h index 1a81cc8618c9756513de3270545df8e7328b74bf..2bc7ee022a96bdf22729911982a004c91183008f 100644 --- a/clang/lib/Headers/riscv_bitmanip.h +++ b/clang/lib/Headers/riscv_bitmanip.h @@ -34,7 +34,7 @@ __riscv_ctz_32(uint32_t __x) { static __inline__ unsigned __attribute__((__always_inline__, __nodebug__)) __riscv_cpop_32(uint32_t __x) { - return __builtin_riscv_cpop_32(__x); + return __builtin_popcount(__x); } #if __riscv_xlen == 64 @@ -55,7 +55,7 @@ __riscv_ctz_64(uint64_t __x) { static __inline__ unsigned __attribute__((__always_inline__, __nodebug__)) __riscv_cpop_64(uint64_t __x) { - return __builtin_riscv_cpop_64(__x); + return __builtin_popcountll(__x); } #endif #endif // defined(__riscv_zbb) @@ -120,7 +120,23 @@ __riscv_zip_32(uint32_t __x) { #endif #endif // defined(__riscv_zbkb) -#if defined(__riscv_zbkc) +#if defined(__riscv_zbc) +#if __riscv_xlen == 32 +static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) +__riscv_clmulr_32(uint32_t __x, uint32_t __y) { + return __builtin_riscv_clmulr_32(__x, __y); +} +#endif + +#if __riscv_xlen == 64 +static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__)) +__riscv_clmulr_64(uint64_t __x, uint64_t __y) { + return __builtin_riscv_clmulr_64(__x, __y); +} +#endif +#endif // defined(__riscv_zbc) + +#if defined(__riscv_zbkc) || defined(__riscv_zbc) static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) __riscv_clmul_32(uint32_t __x, uint32_t __y) { return __builtin_riscv_clmul_32(__x, __y); @@ -144,7 +160,7 @@ __riscv_clmulh_64(uint64_t __x, uint64_t __y) { return __builtin_riscv_clmulh_64(__x, __y); } #endif -#endif // defined(__riscv_zbkc) +#endif // defined(__riscv_zbkc) || defined(__riscv_zbc) #if defined(__riscv_zbkx) #if __riscv_xlen == 32 diff --git a/clang/lib/Headers/usermsrintrin.h b/clang/lib/Headers/usermsrintrin.h index 6d1424ad3b2edd76c1d22d2632c1e954aeb4741e..61388376706dc69f08c7a012eeb32094c51b4ffa 100644 --- a/clang/lib/Headers/usermsrintrin.h +++ b/clang/lib/Headers/usermsrintrin.h @@ -14,12 +14,33 @@ #define __USERMSRINTRIN_H #ifdef __x86_64__ +/// Reads the contents of a 64-bit MSR specified in \a __A into \a dst. +/// +/// This intrinsic corresponds to the URDMSR instruction. +/// \param __A +/// An unsigned long long. +/// +/// \code{.operation} +/// DEST := MSR[__A] +/// \endcode static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("usermsr"))) _urdmsr(unsigned long long __A) { return __builtin_ia32_urdmsr(__A); } +/// Writes the contents of \a __B into the 64-bit MSR specified in \a __A. +/// +/// This intrinsic corresponds to the UWRMSR instruction. +/// +/// \param __A +/// An unsigned long long. +/// \param __B +/// An unsigned long long. +/// +/// \code{.operation} +/// MSR[__A] := __B +/// \endcode static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("usermsr"))) _uwrmsr(unsigned long long __A, unsigned long long __B) { diff --git a/clang/lib/Headers/vecintrin.h b/clang/lib/Headers/vecintrin.h index ecfd6cd1a2f87d87c38d228e6ef67cc2aef2e78d..1f51e32c0d136d6b354b2af42fb8cb487a23d236 100644 --- a/clang/lib/Headers/vecintrin.h +++ b/clang/lib/Headers/vecintrin.h @@ -8359,7 +8359,7 @@ vec_min(__vector double __a, __vector double __b) { static inline __ATTRS_ai __vector unsigned char vec_add_u128(__vector unsigned char __a, __vector unsigned char __b) { - return __builtin_s390_vaq(__a, __b); + return (__vector unsigned char)((__int128)__a + (__int128)__b); } /*-- vec_addc ---------------------------------------------------------------*/ @@ -8388,7 +8388,8 @@ vec_addc(__vector unsigned long long __a, __vector unsigned long long __b) { static inline __ATTRS_ai __vector unsigned char vec_addc_u128(__vector unsigned char __a, __vector unsigned char __b) { - return __builtin_s390_vaccq(__a, __b); + return (__vector unsigned char) + __builtin_s390_vaccq((unsigned __int128)__a, (unsigned __int128)__b); } /*-- vec_adde_u128 ----------------------------------------------------------*/ @@ -8396,7 +8397,9 @@ vec_addc_u128(__vector unsigned char __a, __vector unsigned char __b) { static inline __ATTRS_ai __vector unsigned char vec_adde_u128(__vector unsigned char __a, __vector unsigned char __b, __vector unsigned char __c) { - return __builtin_s390_vacq(__a, __b, __c); + return (__vector unsigned char) + __builtin_s390_vacq((unsigned __int128)__a, (unsigned __int128)__b, + (unsigned __int128)__c); } /*-- vec_addec_u128 ---------------------------------------------------------*/ @@ -8404,7 +8407,9 @@ vec_adde_u128(__vector unsigned char __a, __vector unsigned char __b, static inline __ATTRS_ai __vector unsigned char vec_addec_u128(__vector unsigned char __a, __vector unsigned char __b, __vector unsigned char __c) { - return __builtin_s390_vacccq(__a, __b, __c); + return (__vector unsigned char) + __builtin_s390_vacccq((unsigned __int128)__a, (unsigned __int128)__b, + (unsigned __int128)__c); } /*-- vec_avg ----------------------------------------------------------------*/ @@ -8478,7 +8483,7 @@ vec_gfmsum(__vector unsigned int __a, __vector unsigned int __b) { static inline __ATTRS_o_ai __vector unsigned char vec_gfmsum_128(__vector unsigned long long __a, __vector unsigned long long __b) { - return __builtin_s390_vgfmg(__a, __b); + return (__vector unsigned char)__builtin_s390_vgfmg(__a, __b); } /*-- vec_gfmsum_accum -------------------------------------------------------*/ @@ -8507,7 +8512,8 @@ static inline __ATTRS_o_ai __vector unsigned char vec_gfmsum_accum_128(__vector unsigned long long __a, __vector unsigned long long __b, __vector unsigned char __c) { - return __builtin_s390_vgfmag(__a, __b, __c); + return (__vector unsigned char) + __builtin_s390_vgfmag(__a, __b, (unsigned __int128)__c); } /*-- vec_mladd --------------------------------------------------------------*/ @@ -8797,15 +8803,21 @@ vec_mulo(__vector unsigned int __a, __vector unsigned int __b) { /*-- vec_msum_u128 ----------------------------------------------------------*/ #if __ARCH__ >= 12 +extern __ATTRS_o __vector unsigned char +vec_msum_u128(__vector unsigned long long __a, __vector unsigned long long __b, + __vector unsigned char __c, int __d) + __constant_range(__d, 0, 15); + #define vec_msum_u128(X, Y, Z, W) \ - ((__vector unsigned char)__builtin_s390_vmslg((X), (Y), (Z), (W))); + ((__typeof__((vec_msum_u128)((X), (Y), (Z), (W)))) \ + __builtin_s390_vmslg((X), (Y), (unsigned __int128)(Z), (W))) #endif /*-- vec_sub_u128 -----------------------------------------------------------*/ static inline __ATTRS_ai __vector unsigned char vec_sub_u128(__vector unsigned char __a, __vector unsigned char __b) { - return __builtin_s390_vsq(__a, __b); + return (__vector unsigned char)((__int128)__a - (__int128)__b); } /*-- vec_subc ---------------------------------------------------------------*/ @@ -8834,7 +8846,8 @@ vec_subc(__vector unsigned long long __a, __vector unsigned long long __b) { static inline __ATTRS_ai __vector unsigned char vec_subc_u128(__vector unsigned char __a, __vector unsigned char __b) { - return __builtin_s390_vscbiq(__a, __b); + return (__vector unsigned char) + __builtin_s390_vscbiq((unsigned __int128)__a, (unsigned __int128)__b); } /*-- vec_sube_u128 ----------------------------------------------------------*/ @@ -8842,7 +8855,9 @@ vec_subc_u128(__vector unsigned char __a, __vector unsigned char __b) { static inline __ATTRS_ai __vector unsigned char vec_sube_u128(__vector unsigned char __a, __vector unsigned char __b, __vector unsigned char __c) { - return __builtin_s390_vsbiq(__a, __b, __c); + return (__vector unsigned char) + __builtin_s390_vsbiq((unsigned __int128)__a, (unsigned __int128)__b, + (unsigned __int128)__c); } /*-- vec_subec_u128 ---------------------------------------------------------*/ @@ -8850,7 +8865,9 @@ vec_sube_u128(__vector unsigned char __a, __vector unsigned char __b, static inline __ATTRS_ai __vector unsigned char vec_subec_u128(__vector unsigned char __a, __vector unsigned char __b, __vector unsigned char __c) { - return __builtin_s390_vsbcbiq(__a, __b, __c); + return (__vector unsigned char) + __builtin_s390_vsbcbiq((unsigned __int128)__a, (unsigned __int128)__b, + (unsigned __int128)__c); } /*-- vec_sum2 ---------------------------------------------------------------*/ @@ -8869,12 +8886,12 @@ vec_sum2(__vector unsigned int __a, __vector unsigned int __b) { static inline __ATTRS_o_ai __vector unsigned char vec_sum_u128(__vector unsigned int __a, __vector unsigned int __b) { - return __builtin_s390_vsumqf(__a, __b); + return (__vector unsigned char)__builtin_s390_vsumqf(__a, __b); } static inline __ATTRS_o_ai __vector unsigned char vec_sum_u128(__vector unsigned long long __a, __vector unsigned long long __b) { - return __builtin_s390_vsumqg(__a, __b); + return (__vector unsigned char)__builtin_s390_vsumqg(__a, __b); } /*-- vec_sum4 ---------------------------------------------------------------*/ diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp index c67810ad126b6e2ddab9dafb65e1bc960ab3c518..0f79694d1faac7b9073574bece56f51de9c87526 100644 --- a/clang/lib/Index/IndexSymbol.cpp +++ b/clang/lib/Index/IndexSymbol.cpp @@ -36,7 +36,7 @@ static bool isUnitTest(const ObjCMethodDecl *D) { return false; if (!D->getReturnType()->isVoidType()) return false; - if (!D->getSelector().getNameForSlot(0).startswith("test")) + if (!D->getSelector().getNameForSlot(0).starts_with("test")) return false; return isUnitTestCase(D->getClassInterface()); } diff --git a/clang/lib/IndexSerialization/SerializablePathCollection.cpp b/clang/lib/IndexSerialization/SerializablePathCollection.cpp index bd5f861bf482e511168ca428bdf7046aacb4751b..74ed18a4f612def61128db427752da370a6f238a 100644 --- a/clang/lib/IndexSerialization/SerializablePathCollection.cpp +++ b/clang/lib/IndexSerialization/SerializablePathCollection.cpp @@ -70,11 +70,11 @@ PathPool::DirPath SerializablePathCollection::tryStoreDirPath(StringRef Dir) { const std::string OrigDir = Dir.str(); PathPool::RootDirKind Root = PathPool::RootDirKind::Regular; - if (!SysRoot.empty() && Dir.startswith(SysRoot) && + if (!SysRoot.empty() && Dir.starts_with(SysRoot) && llvm::sys::path::is_separator(Dir[SysRoot.size()])) { Root = PathPool::RootDirKind::SysRoot; Dir = Dir.drop_front(SysRoot.size()); - } else if (!WorkDir.empty() && Dir.startswith(WorkDir) && + } else if (!WorkDir.empty() && Dir.starts_with(WorkDir) && llvm::sys::path::is_separator(Dir[WorkDir.size()])) { Root = PathPool::RootDirKind::CurrentWorkDir; Dir = Dir.drop_front(WorkDir.size()); diff --git a/clang/lib/Interpreter/CodeCompletion.cpp b/clang/lib/Interpreter/CodeCompletion.cpp index c40e11b9d1ece0a3b3f50cfdd6acf7de9ac14bc0..25183ae9eeb99e4dec9855df0dc56bd7bede8e2d 100644 --- a/clang/lib/Interpreter/CodeCompletion.cpp +++ b/clang/lib/Interpreter/CodeCompletion.cpp @@ -12,6 +12,7 @@ #include "clang/Interpreter/CodeCompletion.h" #include "clang/AST/ASTImporter.h" +#include "clang/AST/DeclLookups.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" #include "clang/Basic/IdentifierTable.h" @@ -23,6 +24,8 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/CodeCompleteOptions.h" #include "clang/Sema/Sema.h" +#include "llvm/Support/Debug.h" +#define DEBUG_TYPE "REPLCC" namespace clang { @@ -39,11 +42,15 @@ clang::CodeCompleteOptions getClangCompleteOpts() { class ReplCompletionConsumer : public CodeCompleteConsumer { public: - ReplCompletionConsumer(std::vector &Results) + ReplCompletionConsumer(std::vector &Results, + ReplCodeCompleter &CC) : CodeCompleteConsumer(getClangCompleteOpts()), CCAllocator(std::make_shared()), - CCTUInfo(CCAllocator), Results(Results){}; + CCTUInfo(CCAllocator), Results(Results), CC(CC) {} + // The entry of handling code completion. When the function is called, we + // create a `Context`-based handler (see classes defined below) to handle each + // completion result. void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context, CodeCompletionResult *InResults, unsigned NumResults) final; @@ -56,26 +63,147 @@ private: std::shared_ptr CCAllocator; CodeCompletionTUInfo CCTUInfo; std::vector &Results; + ReplCodeCompleter &CC; +}; + +/// The class CompletionContextHandler contains four interfaces, each of +/// which handles one type of completion result. +/// Its derived classes are used to create concrete handlers based on +/// \c CodeCompletionContext. +class CompletionContextHandler { +protected: + CodeCompletionContext CCC; + std::vector &Results; + +private: + Sema &S; + +public: + CompletionContextHandler(Sema &S, CodeCompletionContext CCC, + std::vector &Results) + : CCC(CCC), Results(Results), S(S) {} + + virtual ~CompletionContextHandler() = default; + /// Converts a Declaration completion result to a completion string, and then + /// stores it in Results. + virtual void handleDeclaration(const CodeCompletionResult &Result) { + auto PreferredType = CCC.getPreferredType(); + if (PreferredType.isNull()) { + Results.push_back(Result.Declaration->getName().str()); + return; + } + + if (auto *VD = dyn_cast(Result.Declaration)) { + auto ArgumentType = VD->getType(); + if (PreferredType->isReferenceType()) { + QualType RT = PreferredType->castAs()->getPointeeType(); + Sema::ReferenceConversions RefConv; + Sema::ReferenceCompareResult RefRelationship = + S.CompareReferenceRelationship(SourceLocation(), RT, ArgumentType, + &RefConv); + switch (RefRelationship) { + case Sema::Ref_Compatible: + case Sema::Ref_Related: + Results.push_back(VD->getName().str()); + break; + case Sema::Ref_Incompatible: + break; + } + } else if (S.Context.hasSameType(ArgumentType, PreferredType)) { + Results.push_back(VD->getName().str()); + } + } + } + + /// Converts a Keyword completion result to a completion string, and then + /// stores it in Results. + virtual void handleKeyword(const CodeCompletionResult &Result) { + auto Prefix = S.getPreprocessor().getCodeCompletionFilter(); + // Add keyword to the completion results only if we are in a type-aware + // situation. + if (!CCC.getBaseType().isNull() || !CCC.getPreferredType().isNull()) + return; + if (StringRef(Result.Keyword).starts_with(Prefix)) + Results.push_back(Result.Keyword); + } + + /// Converts a Pattern completion result to a completion string, and then + /// stores it in Results. + virtual void handlePattern(const CodeCompletionResult &Result) {} + + /// Converts a Macro completion result to a completion string, and then stores + /// it in Results. + virtual void handleMacro(const CodeCompletionResult &Result) {} +}; + +class DotMemberAccessHandler : public CompletionContextHandler { +public: + DotMemberAccessHandler(Sema &S, CodeCompletionContext CCC, + std::vector &Results) + : CompletionContextHandler(S, CCC, Results) {} + void handleDeclaration(const CodeCompletionResult &Result) override { + auto *ID = Result.Declaration->getIdentifier(); + if (!ID) + return; + if (!isa(Result.Declaration)) + return; + const auto *Fun = cast(Result.Declaration); + if (Fun->getParent()->getCanonicalDecl() == + CCC.getBaseType()->getAsCXXRecordDecl()->getCanonicalDecl()) { + LLVM_DEBUG(llvm::dbgs() << "[In HandleCodeCompleteDOT] Name : " + << ID->getName() << "\n"); + Results.push_back(ID->getName().str()); + } + } + + void handleKeyword(const CodeCompletionResult &Result) override {} }; void ReplCompletionConsumer::ProcessCodeCompleteResults( class Sema &S, CodeCompletionContext Context, CodeCompletionResult *InResults, unsigned NumResults) { - for (unsigned I = 0; I < NumResults; ++I) { + + auto Prefix = S.getPreprocessor().getCodeCompletionFilter(); + CC.Prefix = Prefix; + + std::unique_ptr CCH; + + // initialize fine-grained code completion handler based on the code + // completion context. + switch (Context.getKind()) { + case CodeCompletionContext::CCC_DotMemberAccess: + CCH.reset(new DotMemberAccessHandler(S, Context, this->Results)); + break; + default: + CCH.reset(new CompletionContextHandler(S, Context, this->Results)); + }; + + for (unsigned I = 0; I < NumResults; I++) { auto &Result = InResults[I]; switch (Result.Kind) { case CodeCompletionResult::RK_Declaration: - if (auto *ID = Result.Declaration->getIdentifier()) { - Results.push_back(ID->getName().str()); + if (Result.Hidden) { + break; + } + if (!Result.Declaration->getDeclName().isIdentifier() || + !Result.Declaration->getName().starts_with(Prefix)) { + break; } + CCH->handleDeclaration(Result); break; case CodeCompletionResult::RK_Keyword: - Results.push_back(Result.Keyword); + CCH->handleKeyword(Result); break; - default: + case CodeCompletionResult::RK_Macro: + CCH->handleMacro(Result); + break; + case CodeCompletionResult::RK_Pattern: + CCH->handlePattern(Result); break; } } + + std::sort(Results.begin(), Results.end()); } class IncrementalSyntaxOnlyAction : public SyntaxOnlyAction { @@ -118,6 +246,16 @@ void IncrementalSyntaxOnlyAction::ExecuteAction() { CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage( true); + // Load all external decls into current context. Under the hood, it calls + // ExternalSource::completeVisibleDeclsMap, which make all decls on the redecl + // chain visible. + // + // This is crucial to code completion on dot members, since a bound variable + // before "." would be otherwise treated out-of-scope. + // + // clang-repl> Foo f1; + // clang-repl> f1. + CI.getASTContext().getTranslationUnitDecl()->lookups(); SyntaxOnlyAction::ExecuteAction(); } @@ -134,6 +272,7 @@ ExternalSource::ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM, bool ExternalSource::FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { + IdentifierTable &ParentIdTable = ParentASTCtxt.Idents; auto ParentDeclName = @@ -159,29 +298,67 @@ void ExternalSource::completeVisibleDeclsMap( for (auto *DeclCtxt = ParentTUDeclCtxt; DeclCtxt != nullptr; DeclCtxt = DeclCtxt->getPreviousDecl()) { for (auto &IDeclContext : DeclCtxt->decls()) { - if (NamedDecl *Decl = llvm::dyn_cast(IDeclContext)) { - if (auto DeclOrErr = Importer->Import(Decl)) { - if (NamedDecl *importedNamedDecl = - llvm::dyn_cast(*DeclOrErr)) { - SetExternalVisibleDeclsForName(ChildDeclContext, - importedNamedDecl->getDeclName(), - importedNamedDecl); - } - - } else { - llvm::consumeError(DeclOrErr.takeError()); - } + if (!llvm::isa(IDeclContext)) + continue; + + NamedDecl *Decl = llvm::cast(IDeclContext); + + auto DeclOrErr = Importer->Import(Decl); + if (!DeclOrErr) { + // if an error happens, it usually means the decl has already been + // imported or the decl is a result of a failed import. But in our + // case, every import is fresh each time code completion is + // triggered. So Import usually doesn't fail. If it does, it just means + // the related decl can't be used in code completion and we can safely + // drop it. + llvm::consumeError(DeclOrErr.takeError()); + continue; } + + if (!llvm::isa(*DeclOrErr)) + continue; + + NamedDecl *importedNamedDecl = llvm::cast(*DeclOrErr); + + SetExternalVisibleDeclsForName(ChildDeclContext, + importedNamedDecl->getDeclName(), + importedNamedDecl); + + if (!llvm::isa(importedNamedDecl)) + continue; + + auto *Record = llvm::cast(importedNamedDecl); + + if (auto Err = Importer->ImportDefinition(Decl)) { + // the same as above + consumeError(std::move(Err)); + continue; + } + + Record->setHasLoadedFieldsFromExternalStorage(true); + LLVM_DEBUG(llvm::dbgs() + << "\nCXXRecrod : " << Record->getName() << " size(methods): " + << std::distance(Record->method_begin(), Record->method_end()) + << " has def?: " << Record->hasDefinition() + << " # (methods): " + << std::distance(Record->getDefinition()->method_begin(), + Record->getDefinition()->method_end()) + << "\n"); + for (auto *Meth : Record->methods()) + SetExternalVisibleDeclsForName(ChildDeclContext, Meth->getDeclName(), + Meth); } ChildDeclContext->setHasExternalLexicalStorage(false); } } -void codeComplete(CompilerInstance *InterpCI, llvm::StringRef Content, - unsigned Line, unsigned Col, const CompilerInstance *ParentCI, - std::vector &CCResults) { +void ReplCodeCompleter::codeComplete(CompilerInstance *InterpCI, + llvm::StringRef Content, unsigned Line, + unsigned Col, + const CompilerInstance *ParentCI, + std::vector &CCResults) { auto DiagOpts = DiagnosticOptions(); - auto consumer = ReplCompletionConsumer(CCResults); + auto consumer = ReplCompletionConsumer(CCResults, *this); auto diag = InterpCI->getDiagnosticsPtr(); std::unique_ptr AU(ASTUnit::LoadFromCompilerInvocationAction( diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 7968c62cbd3e7b30d9bef9446f73203b5428fab5..c9fcef5b5b5af1398e1290551ae4eb6afe07f64b 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -319,6 +319,10 @@ const CompilerInstance *Interpreter::getCompilerInstance() const { return IncrParser->getCI(); } +CompilerInstance *Interpreter::getCompilerInstance() { + return IncrParser->getCI(); +} + llvm::Expected Interpreter::getExecutionEngine() { if (!IncrExecutor) { if (auto Err = CreateExecutor()) diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp index 22a1532c2d93838bf66f3dd27a1ea69d985d2d1f..00bf880726ee3e0120495e8ee71ab9973d5419e2 100644 --- a/clang/lib/Lex/HeaderMap.cpp +++ b/clang/lib/Lex/HeaderMap.cpp @@ -11,16 +11,17 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/HeaderMap.h" -#include "clang/Lex/HeaderMapTypes.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/FileManager.h" +#include "clang/Lex/HeaderMapTypes.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SwapByteOrder.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/SystemZ/zOSSupport.h" #include #include #include diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index c03cf19688d961adb9a02e33b4390b6cbf2b4748..0f1090187734ff25bdc462ee8de45f7f354f1c92 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -796,7 +796,7 @@ static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader, } else if (*I == "PrivateHeaders") { ++FoundComp; IsPrivateHeader = true; - } else if (I->endswith(".framework")) { + } else if (I->ends_with(".framework")) { StringRef Name = I->drop_back(10); // Drop .framework // Need to reset the strings and counter to support nested frameworks. FrameworkName.clear(); @@ -1085,7 +1085,7 @@ OptionalFileEntryRef HeaderSearch::LookupFile( // If the filename matches a known system header prefix, override // whether the file is a system header. for (unsigned j = SystemHeaderPrefixes.size(); j; --j) { - if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) { + if (Filename.starts_with(SystemHeaderPrefixes[j - 1].first)) { HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System : SrcMgr::C_User; break; @@ -1656,7 +1656,8 @@ bool HeaderSearch::findUsableModuleForFrameworkHeader( } static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File, - FileManager &FileMgr) { + FileManager &FileMgr, + DiagnosticsEngine &Diags) { StringRef Filename = llvm::sys::path::filename(File.getName()); SmallString<128> PrivateFilename(File.getDir().getName()); if (Filename == "module.map") @@ -1665,7 +1666,14 @@ static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File, llvm::sys::path::append(PrivateFilename, "module.private.modulemap"); else return std::nullopt; - return FileMgr.getOptionalFileRef(PrivateFilename); + auto PMMFile = FileMgr.getOptionalFileRef(PrivateFilename); + if (PMMFile) { + if (Filename == "module.map") + Diags.Report(diag::warn_deprecated_module_dot_map) + << PrivateFilename << 1 + << File.getDir().getName().ends_with(".framework"); + } + return PMMFile; } bool HeaderSearch::loadModuleMapFile(FileEntryRef File, bool IsSystem, @@ -1694,7 +1702,7 @@ bool HeaderSearch::loadModuleMapFile(FileEntryRef File, bool IsSystem, StringRef DirName(Dir->getName()); if (llvm::sys::path::filename(DirName) == "Modules") { DirName = llvm::sys::path::parent_path(DirName); - if (DirName.endswith(".framework")) + if (DirName.ends_with(".framework")) if (auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName)) Dir = *MaybeDir; // FIXME: This assert can fail if there's a race between the above check @@ -1731,7 +1739,8 @@ HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem, } // Try to load a corresponding private module map. - if (OptionalFileEntryRef PMMFile = getPrivateModuleMap(File, FileMgr)) { + if (OptionalFileEntryRef PMMFile = + getPrivateModuleMap(File, FileMgr, Diags)) { if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, Dir)) { LoadedModuleMaps[File] = false; return LMM_InvalidModuleMap; @@ -1755,11 +1764,14 @@ HeaderSearch::lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework) { if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) return *F; - // Continue to allow module.map + // Continue to allow module.map, but warn it's deprecated. ModuleMapFileName = Dir.getName(); llvm::sys::path::append(ModuleMapFileName, "module.map"); - if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) + if (auto F = FileMgr.getOptionalFileRef(ModuleMapFileName)) { + Diags.Report(diag::warn_deprecated_module_dot_map) + << ModuleMapFileName << 0 << IsFramework; return *F; + } // For frameworks, allow to have a private module map with a preferred // spelling when a public module map is absent. @@ -1965,10 +1977,10 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics( // Special case Apple .sdk folders since the search path is typically a // symlink like `iPhoneSimulator14.5.sdk` while the file is instead // located in `iPhoneSimulator.sdk` (the real folder). - if (NI->endswith(".sdk") && DI->endswith(".sdk")) { + if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) { StringRef NBasename = path::stem(*NI); StringRef DBasename = path::stem(*DI); - if (DBasename.startswith(NBasename)) + if (DBasename.starts_with(NBasename)) continue; } diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp index 5b1b7c859c85d9346858ee7472f6cfd3d9838f8e..2218db15013d926506c576f8a533596ac595ee72 100644 --- a/clang/lib/Lex/InitHeaderSearch.cpp +++ b/clang/lib/Lex/InitHeaderSearch.cpp @@ -141,8 +141,8 @@ bool InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group, StringRef MappedPathStr = Path.toStringRef(MappedPathStorage); // If use system headers while cross-compiling, emit the warning. - if (HasSysroot && (MappedPathStr.startswith("/usr/include") || - MappedPathStr.startswith("/usr/local/include"))) { + if (HasSysroot && (MappedPathStr.starts_with("/usr/include") || + MappedPathStr.starts_with("/usr/local/include"))) { Headers.getDiags().Report(diag::warn_poison_system_directories) << MappedPathStr; } diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index f4f1daab857f043696585083e3c99a0839abd1ea..50b56265f6e164d9f5f24546197db33d141d137f 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -3212,8 +3212,8 @@ bool Lexer::IsStartOfConflictMarker(const char *CurPtr) { return false; // Check to see if we have <<<<<<< or >>>>. - if (!StringRef(CurPtr, BufferEnd - CurPtr).startswith("<<<<<<<") && - !StringRef(CurPtr, BufferEnd - CurPtr).startswith(">>>> ")) + if (!StringRef(CurPtr, BufferEnd - CurPtr).starts_with("<<<<<<<") && + !StringRef(CurPtr, BufferEnd - CurPtr).starts_with(">>>> ")) return false; // If we have a situation where we don't care about conflict markers, ignore diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index d35c282543c564d6ac94f8db51d50d38f5a4f7db..ea5d13deb11470325a4e54974a1366e528566daf 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -235,7 +235,7 @@ OptionalFileEntryRef ModuleMap::findHeader( llvm::sys::path::append(FullPathName, RelativePathName); auto NormalHdrFile = GetFile(FullPathName); - if (!NormalHdrFile && Directory->getName().endswith(".framework")) { + if (!NormalHdrFile && Directory->getName().ends_with(".framework")) { // The lack of 'framework' keyword in a module declaration it's a simple // mistake we can diagnose when the header exists within the proper // framework style path. @@ -1034,7 +1034,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir, if (inferred == InferredDirectories.end()) { // We haven't looked here before. Load a module map, if there is // one. - bool IsFrameworkDir = Parent.endswith(".framework"); + bool IsFrameworkDir = Parent.ends_with(".framework"); if (OptionalFileEntryRef ModMapFile = HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) { parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir); @@ -1125,7 +1125,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir, Dir = FS.dir_begin(SubframeworksDirName, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { - if (!StringRef(Dir->path()).endswith(".framework")) + if (!StringRef(Dir->path()).ends_with(".framework")) continue; if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) { @@ -1337,7 +1337,7 @@ ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl &Path) { // Modules/ not Versions/A/Modules. if (llvm::sys::path::filename(Dir) == "Modules") { StringRef Parent = llvm::sys::path::parent_path(Dir); - if (Parent.endswith(".framework")) + if (Parent.ends_with(".framework")) Dir = Parent; } @@ -2119,8 +2119,8 @@ void ModuleMapParser::parseModuleDecl() { ActiveModule->Directory = Directory; StringRef MapFileName(ModuleMapFile.getName()); - if (MapFileName.endswith("module.private.modulemap") || - MapFileName.endswith("module_private.map")) { + if (MapFileName.ends_with("module.private.modulemap") || + MapFileName.ends_with("module_private.map")) { ActiveModule->ModuleMapIsPrivate = true; } diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 14003480d7fa2e91f38a363a7932879fec2f2d9e..9f82a6d073e3bac8f763330599d4d1235072b45c 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -164,13 +164,13 @@ static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, return false; // C defines macros starting with __STDC, and C++ defines macros starting with // __STDCPP - if (MacroName.startswith("__STDC")) + if (MacroName.starts_with("__STDC")) return true; // C++ defines the __cplusplus macro if (MacroName == "__cplusplus") return true; // C++ defines various feature-test macros starting with __cpp - if (MacroName.startswith("__cpp")) + if (MacroName.starts_with("__cpp")) return true; // Anything else isn't language-defined return false; @@ -646,7 +646,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, Directive = StringRef(DirectiveBuf, IdLen); } - if (Directive.startswith("if")) { + if (Directive.starts_with("if")) { StringRef Sub = Directive.substr(2); if (Sub.empty() || // "if" Sub == "def" || // "ifdef" @@ -1858,11 +1858,18 @@ static void diagnoseAutoModuleImport( // path to the file, build a properly-cased replacement in the vector, // and return true if the replacement should be suggested. static bool trySimplifyPath(SmallVectorImpl &Components, - StringRef RealPathName) { + StringRef RealPathName, + llvm::sys::path::Style Separator) { auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName); auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName); int Cnt = 0; bool SuggestReplacement = false; + + auto IsSep = [Separator](StringRef Component) { + return Component.size() == 1 && + llvm::sys::path::is_separator(Component[0], Separator); + }; + // Below is a best-effort to handle ".." in paths. It is admittedly // not 100% correct in the presence of symlinks. for (auto &Component : llvm::reverse(Components)) { @@ -1872,10 +1879,11 @@ static bool trySimplifyPath(SmallVectorImpl &Components, } else if (Cnt) { --Cnt; } else if (RealPathComponentIter != RealPathComponentEnd) { - if (Component != *RealPathComponentIter) { - // If these path components differ by more than just case, then we - // may be looking at symlinked paths. Bail on this diagnostic to avoid - // noisy false positives. + if (!IsSep(Component) && !IsSep(*RealPathComponentIter) && + Component != *RealPathComponentIter) { + // If these non-separator path components differ by more than just case, + // then we may be looking at symlinked paths. Bail on this diagnostic to + // avoid noisy false positives. SuggestReplacement = RealPathComponentIter->equals_insensitive(Component); if (!SuggestReplacement) @@ -2451,7 +2459,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport( } #endif - if (trySimplifyPath(Components, RealPathName)) { + if (trySimplifyPath(Components, RealPathName, BackslashStyle)) { SmallString<128> Path; Path.reserve(Name.size()+2); Path.push_back(isAngled ? '<' : '"'); @@ -2474,7 +2482,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport( // got copied when the C: was processed and we want to skip that entry. if (!(Component.size() == 1 && IsSep(Component[0]))) Path.append(Component); - else if (!Path.empty()) + else if (Path.size() != 1) continue; // Append the separator(s) the user used, or the close quote @@ -2788,14 +2796,14 @@ static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, return false; StringRef ValueText = II->getName(); StringRef TrimmedValue = ValueText; - if (!ValueText.startswith("__")) { - if (ValueText.startswith("_")) + if (!ValueText.starts_with("__")) { + if (ValueText.starts_with("_")) TrimmedValue = TrimmedValue.drop_front(1); else return false; } else { TrimmedValue = TrimmedValue.drop_front(2); - if (TrimmedValue.endswith("__")) + if (TrimmedValue.ends_with("__")) TrimmedValue = TrimmedValue.drop_back(2); } return TrimmedValue.equals(MacroText); diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 269984aae07bf288a283fbe37080aec13493c467..1feb0eb18d71e6eaa18c0acd6ba596c526b39d15 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -267,7 +267,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, const StringRef IdentifierName = II->getName(); if (llvm::any_of(UndefPrefixes, [&IdentifierName](const std::string &Prefix) { - return IdentifierName.startswith(Prefix); + return IdentifierName.starts_with(Prefix); })) PP.Diag(PeekTok, diag::warn_pp_undef_prefix) << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II; diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 30c4abdbad8aa4462552d1639651f9068d1dbc17..ad02f31209b0b7804447e2430013c0933745a416 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1136,7 +1136,8 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { const LangOptions &LangOpts = PP.getLangOpts(); // Normalize the feature name, __foo__ becomes foo. - if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4) + if (Feature.starts_with("__") && Feature.ends_with("__") && + Feature.size() >= 4) Feature = Feature.substr(2, Feature.size() - 4); #define FEATURE(Name, Predicate) .Case(#Name, Predicate) @@ -1162,7 +1163,7 @@ static bool HasExtension(const Preprocessor &PP, StringRef Extension) { const LangOptions &LangOpts = PP.getLangOpts(); // Normalize the extension name, __foo__ becomes foo. - if (Extension.startswith("__") && Extension.endswith("__") && + if (Extension.starts_with("__") && Extension.ends_with("__") && Extension.size() >= 4) Extension = Extension.substr(2, Extension.size() - 4); @@ -1691,9 +1692,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // as being "builtin functions", even if the syntax isn't a valid // function call (for example, because the builtin takes a type // argument). - if (II->getName().startswith("__builtin_") || - II->getName().startswith("__is_") || - II->getName().startswith("__has_")) + if (II->getName().starts_with("__builtin_") || + II->getName().starts_with("__is_") || + II->getName().starts_with("__has_")) return true; return llvm::StringSwitch(II->getName()) .Case("__array_rank", true) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index ece3698967e2f67e0c7044f3a179a3742985b2d4..ed006f9d67de454c43e85c43007aef8da6f13ae1 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -84,7 +84,7 @@ TypeResult Parser::ParseTypeName(SourceRange *Range, DeclaratorContext Context, /// Normalizes an attribute name by dropping prefixed and suffixed __. static StringRef normalizeAttrName(StringRef Name) { - if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) + if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__")) return Name.drop_front(2).drop_back(2); return Name; } @@ -7854,7 +7854,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { bool IsUnqual = Tok.is(tok::kw_typeof_unqual); const IdentifierInfo *II = Tok.getIdentifierInfo(); - if (getLangOpts().C23 && !II->getName().startswith("__")) + if (getLangOpts().C23 && !II->getName().starts_with("__")) Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName(); Token OpTok = Tok; diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 2fc364fc811b3245f9a37fac80920ad81872e3f2..ef9ea6575205cdf31f79462d456b54d14d416e8b 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1311,18 +1311,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( D.takeAttributes(Attributes); } - // Helper to emit a warning if we see a CUDA host/device/global attribute - // after '(...)'. nvcc doesn't accept this. - auto WarnIfHasCUDATargetAttr = [&] { - if (getLangOpts().CUDA) - for (const ParsedAttr &A : Attributes) - if (A.getKind() == ParsedAttr::AT_CUDADevice || - A.getKind() == ParsedAttr::AT_CUDAHost || - A.getKind() == ParsedAttr::AT_CUDAGlobal) - Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) - << A.getAttrName()->getName(); - }; - MultiParseScope TemplateParamScope(*this); if (Tok.is(tok::less)) { Diag(Tok, getLangOpts().CPlusPlus20 @@ -1377,91 +1365,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( bool HasSpecifiers = false; SourceLocation MutableLoc; - auto ParseConstexprAndMutableSpecifiers = [&] { - // GNU-style attributes must be parsed before the mutable specifier to - // be compatible with GCC. MSVC-style attributes must be parsed before - // the mutable specifier to be compatible with MSVC. - MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes); - // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update - // the DeclEndLoc. - SourceLocation ConstexprLoc; - SourceLocation ConstevalLoc; - SourceLocation StaticLoc; - - tryConsumeLambdaSpecifierToken(*this, MutableLoc, StaticLoc, ConstexprLoc, - ConstevalLoc, DeclEndLoc); - - DiagnoseStaticSpecifierRestrictions(*this, StaticLoc, MutableLoc, Intro); - - addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS); - addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); - addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); - }; - - auto ParseLambdaSpecifiers = - [&](MutableArrayRef ParamInfo, - SourceLocation EllipsisLoc) { - // Parse exception-specification[opt]. - ExceptionSpecificationType ESpecType = EST_None; - SourceRange ESpecRange; - SmallVector DynamicExceptions; - SmallVector DynamicExceptionRanges; - ExprResult NoexceptExpr; - CachedTokens *ExceptionSpecTokens; - - ESpecType = tryParseExceptionSpecification( - /*Delayed=*/false, ESpecRange, DynamicExceptions, - DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens); - - if (ESpecType != EST_None) - DeclEndLoc = ESpecRange.getEnd(); - - // Parse attribute-specifier[opt]. - if (MaybeParseCXX11Attributes(Attributes)) - DeclEndLoc = Attributes.Range.getEnd(); - - // Parse OpenCL addr space attribute. - if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local, - tok::kw___constant, tok::kw___generic)) { - ParseOpenCLQualifiers(DS.getAttributes()); - ConsumeToken(); - } - - SourceLocation FunLocalRangeEnd = DeclEndLoc; - - // Parse trailing-return-type[opt]. - if (Tok.is(tok::arrow)) { - FunLocalRangeEnd = Tok.getLocation(); - SourceRange Range; - TrailingReturnType = ParseTrailingReturnType( - Range, /*MayBeFollowedByDirectInit*/ false); - TrailingReturnTypeLoc = Range.getBegin(); - if (Range.getEnd().isValid()) - DeclEndLoc = Range.getEnd(); - } - - SourceLocation NoLoc; - D.AddTypeInfo( - DeclaratorChunk::getFunction( - /*HasProto=*/true, - /*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(), - ParamInfo.size(), EllipsisLoc, RParenLoc, - /*RefQualifierIsLvalueRef=*/true, - /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, ESpecRange, - DynamicExceptions.data(), DynamicExceptionRanges.data(), - DynamicExceptions.size(), - NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, - /*ExceptionSpecTokens*/ nullptr, - /*DeclsInPrototype=*/std::nullopt, LParenLoc, FunLocalRangeEnd, - D, TrailingReturnType, TrailingReturnTypeLoc, &DS), - std::move(Attributes), DeclEndLoc); - - Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); - - if (HasParentheses && Tok.is(tok::kw_requires)) - ParseTrailingRequiresClause(D); - }; - ParseScope Prototype(this, Scope::FunctionPrototypeScope | Scope::FunctionDeclarationScope | Scope::DeclScope); @@ -1511,18 +1414,104 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( << FixItHint::CreateInsertion(Tok.getLocation(), "() "); } - if (HasParentheses || HasSpecifiers) - ParseConstexprAndMutableSpecifiers(); + if (HasParentheses || HasSpecifiers) { + // GNU-style attributes must be parsed before the mutable specifier to + // be compatible with GCC. MSVC-style attributes must be parsed before + // the mutable specifier to be compatible with MSVC. + MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes); + // Parse mutable-opt and/or constexpr-opt or consteval-opt, and update + // the DeclEndLoc. + SourceLocation ConstexprLoc; + SourceLocation ConstevalLoc; + SourceLocation StaticLoc; + + tryConsumeLambdaSpecifierToken(*this, MutableLoc, StaticLoc, ConstexprLoc, + ConstevalLoc, DeclEndLoc); + + DiagnoseStaticSpecifierRestrictions(*this, StaticLoc, MutableLoc, Intro); + + addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS); + addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); + addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); + } Actions.ActOnLambdaClosureParameters(getCurScope(), ParamInfo); if (!HasParentheses) Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); - if (HasSpecifiers || HasParentheses) - ParseLambdaSpecifiers(ParamInfo, EllipsisLoc); + if (HasSpecifiers || HasParentheses) { + // Parse exception-specification[opt]. + ExceptionSpecificationType ESpecType = EST_None; + SourceRange ESpecRange; + SmallVector DynamicExceptions; + SmallVector DynamicExceptionRanges; + ExprResult NoexceptExpr; + CachedTokens *ExceptionSpecTokens; + + ESpecType = tryParseExceptionSpecification( + /*Delayed=*/false, ESpecRange, DynamicExceptions, + DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens); + + if (ESpecType != EST_None) + DeclEndLoc = ESpecRange.getEnd(); + + // Parse attribute-specifier[opt]. + if (MaybeParseCXX11Attributes(Attributes)) + DeclEndLoc = Attributes.Range.getEnd(); + + // Parse OpenCL addr space attribute. + if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local, + tok::kw___constant, tok::kw___generic)) { + ParseOpenCLQualifiers(DS.getAttributes()); + ConsumeToken(); + } + + SourceLocation FunLocalRangeEnd = DeclEndLoc; + + // Parse trailing-return-type[opt]. + if (Tok.is(tok::arrow)) { + FunLocalRangeEnd = Tok.getLocation(); + SourceRange Range; + TrailingReturnType = + ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false); + TrailingReturnTypeLoc = Range.getBegin(); + if (Range.getEnd().isValid()) + DeclEndLoc = Range.getEnd(); + } + + SourceLocation NoLoc; + D.AddTypeInfo(DeclaratorChunk::getFunction( + /*HasProto=*/true, + /*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(), + ParamInfo.size(), EllipsisLoc, RParenLoc, + /*RefQualifierIsLvalueRef=*/true, + /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, + ESpecRange, DynamicExceptions.data(), + DynamicExceptionRanges.data(), DynamicExceptions.size(), + NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, + /*ExceptionSpecTokens*/ nullptr, + /*DeclsInPrototype=*/std::nullopt, LParenLoc, + FunLocalRangeEnd, D, TrailingReturnType, + TrailingReturnTypeLoc, &DS), + std::move(Attributes), DeclEndLoc); - WarnIfHasCUDATargetAttr(); + Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); + + if (HasParentheses && Tok.is(tok::kw_requires)) + ParseTrailingRequiresClause(D); + } + + // Emit a warning if we see a CUDA host/device/global attribute + // after '(...)'. nvcc doesn't accept this. + if (getLangOpts().CUDA) { + for (const ParsedAttr &A : Attributes) + if (A.getKind() == ParsedAttr::AT_CUDADevice || + A.getKind() == ParsedAttr::AT_CUDAHost || + A.getKind() == ParsedAttr::AT_CUDAGlobal) + Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) + << A.getAttrName()->getName(); + } Prototype.Exit(); diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index f7f096762e91a64b25eca104d1c352bbff9f4480..67325f0a286a999d9be7e11b2a649ca018f20de1 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -69,6 +69,29 @@ OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) { .Default(OpenACCDirectiveKindEx::Invalid); } +// Translate single-token string representations to the OpenCC Clause Kind. +OpenACCClauseKind getOpenACCClauseKind(Token Tok) { + // auto is a keyword in some language modes, so make sure we parse it + // correctly. + if (Tok.is(tok::kw_auto)) + return OpenACCClauseKind::Auto; + + if (!Tok.is(tok::identifier)) + return OpenACCClauseKind::Invalid; + + return llvm::StringSwitch( + Tok.getIdentifierInfo()->getName()) + .Case("auto", OpenACCClauseKind::Auto) + .Case("finalize", OpenACCClauseKind::Finalize) + .Case("if_present", OpenACCClauseKind::IfPresent) + .Case("independent", OpenACCClauseKind::Independent) + .Case("nohost", OpenACCClauseKind::NoHost) + .Case("seq", OpenACCClauseKind::Seq) + .Case("vector", OpenACCClauseKind::Vector) + .Case("worker", OpenACCClauseKind::Worker) + .Default(OpenACCClauseKind::Invalid); +} + // Since 'atomic' is effectively a compound directive, this will decode the // second part of the directive. OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) { @@ -164,6 +187,10 @@ ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok, return OpenACCDirectiveKind::Invalid; } + // Consume the second name anyway, this way we can continue on without making + // this oddly look like a clause. + P.ConsumeAnyToken(); + if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) { if (!SecondTok.is(tok::identifier)) P.Diag(SecondTok, diag::err_expected) << tok::identifier; @@ -174,8 +201,6 @@ ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok, return OpenACCDirectiveKind::Invalid; } - P.ConsumeToken(); - return ExtDirKind == OpenACCDirectiveKindEx::Enter ? OpenACCDirectiveKind::EnterData : OpenACCDirectiveKind::ExitData; @@ -208,6 +233,10 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { // introspect on the spelling before then. if (FirstTok.isNot(tok::identifier)) { P.Diag(FirstTok, diag::err_acc_missing_directive); + + if (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) + P.ConsumeAnyToken(); + return OpenACCDirectiveKind::Invalid; } @@ -262,12 +291,57 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { return DirKind; } +// The OpenACC Clause List is a comma or space-delimited list of clauses (see +// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't +// really have its owner grammar and each individual one has its own definition. +// However, they all are named with a single-identifier (or auto!) token, +// followed in some cases by either braces or parens. +bool ParseOpenACCClause(Parser &P) { + if (!P.getCurToken().isOneOf(tok::identifier, tok::kw_auto)) + return P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier; + + OpenACCClauseKind Kind = getOpenACCClauseKind(P.getCurToken()); + + if (Kind == OpenACCClauseKind::Invalid) + return P.Diag(P.getCurToken(), diag::err_acc_invalid_clause) + << P.getCurToken().getIdentifierInfo(); + + // Consume the clause name. + P.ConsumeToken(); + + // FIXME: For future clauses, we need to handle parens/etc below. + return false; +} + +// Skip until we see the end of pragma token, but don't consume it. This is us +// just giving up on the rest of the pragma so we can continue executing. We +// have to do this because 'SkipUntil' considers paren balancing, which isn't +// what we want. +void SkipUntilEndOfDirective(Parser &P) { + while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) + P.ConsumeAnyToken(); +} + +// OpenACC 3.3, section 1.7: +// To simplify the specification and convey appropriate constraint information, +// a pqr-list is a comma-separated list of pdr items. The one exception is a +// clause-list, which is a list of one or more clauses optionally separated by +// commas. void ParseOpenACCClauseList(Parser &P) { - // FIXME: In the future, we'll start parsing the clauses here, but for now we - // haven't implemented that, so just emit the unimplemented diagnostic and - // fail reasonably. - if (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) - P.Diag(P.getCurToken(), diag::warn_pragma_acc_unimplemented_clause_parsing); + bool FirstClause = true; + while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) { + // Comma is optional in a clause-list. + if (!FirstClause && P.getCurToken().is(tok::comma)) + P.ConsumeToken(); + FirstClause = false; + + // Recovering from a bad clause is really difficult, so we just give up on + // error. + if (ParseOpenACCClause(P)) { + SkipUntilEndOfDirective(P); + return; + } + } } } // namespace @@ -499,7 +573,9 @@ void Parser::ParseOpenACCDirective() { ParseOpenACCClauseList(*this); Diag(getCurToken(), diag::warn_pragma_acc_unimplemented); - SkipUntil(tok::annot_pragma_openacc_end); + assert(Tok.is(tok::annot_pragma_openacc_end) && + "Didn't parse all OpenACC Clauses"); + ConsumeAnnotationToken(); } // Parse OpenACC directive on a declaration. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index ec67faf7dcaf863985a2b595e517d3007ff3fa68..b703c2d9b8e04d831c1908dc26b689332879866d 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -2645,7 +2645,7 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc, auto &SrcMgr = PP.getSourceManager(); auto FE = SrcMgr.getFileEntryRefForID(SrcMgr.getFileID(AtLoc)); if (FE && llvm::sys::path::parent_path(FE->getDir().getName()) - .endswith(".framework")) + .ends_with(".framework")) Diags.Report(AtLoc, diag::warn_atimport_in_framework_header); } diff --git a/clang/lib/Rewrite/Rewriter.cpp b/clang/lib/Rewrite/Rewriter.cpp index 0896221dd0bdeb5672b89ea2d450f6faa78b8d3c..0e6ae365064463bf6a6866a8a21c6a5c4a1dcb7a 100644 --- a/clang/lib/Rewrite/Rewriter.cpp +++ b/clang/lib/Rewrite/Rewriter.cpp @@ -386,7 +386,7 @@ bool Rewriter::IncreaseIndentation(CharSourceRange range, } if (parentSpace.size() >= startSpace.size()) return true; - if (!startSpace.startswith(parentSpace)) + if (!startSpace.starts_with(parentSpace)) return true; StringRef indent = startSpace.substr(parentSpace.size()); @@ -399,7 +399,7 @@ bool Rewriter::IncreaseIndentation(CharSourceRange range, while (isWhitespaceExceptNL(MB[i])) ++i; StringRef origIndent = MB.substr(offs, i-offs); - if (origIndent.startswith(startSpace)) + if (origIndent.starts_with(startSpace)) RB.InsertText(offs, indent, /*InsertAfter=*/false); } diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 9caa1a8431e9021cf01cf45930e211acc4a467fe..350bd78b57107bbfaa0dde13af5ec7c18af9b503 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -630,15 +630,16 @@ bool PrintingCodeCompleteConsumer::isResultFilteredOut( StringRef Filter, CodeCompletionResult Result) { switch (Result.Kind) { case CodeCompletionResult::RK_Declaration: - return !(Result.Declaration->getIdentifier() && - Result.Declaration->getIdentifier()->getName().startswith(Filter)); + return !( + Result.Declaration->getIdentifier() && + Result.Declaration->getIdentifier()->getName().starts_with(Filter)); case CodeCompletionResult::RK_Keyword: - return !StringRef(Result.Keyword).startswith(Filter); + return !StringRef(Result.Keyword).starts_with(Filter); case CodeCompletionResult::RK_Macro: - return !Result.Macro->getName().startswith(Filter); + return !Result.Macro->getName().starts_with(Filter); case CodeCompletionResult::RK_Pattern: return !(Result.Pattern->getTypedText() && - StringRef(Result.Pattern->getTypedText()).startswith(Filter)); + StringRef(Result.Pattern->getTypedText()).starts_with(Filter)); } llvm_unreachable("Unknown code completion result Kind."); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index cdb6e9584e9554104e3b4921f15d4752440661fe..da0570b7b0f1e6dcb7a4182654f34537947a1e8d 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1219,8 +1219,8 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, if (IsChkVariant) { FunctionName = FunctionName.drop_front(std::strlen("__builtin___")); FunctionName = FunctionName.drop_back(std::strlen("_chk")); - } else if (FunctionName.startswith("__builtin_")) { - FunctionName = FunctionName.drop_front(std::strlen("__builtin_")); + } else { + FunctionName.consume_front("__builtin_"); } return FunctionName; }; @@ -3156,7 +3156,6 @@ static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, const FunctionDecl *FD, ArmStreamingType BuiltinType) { ArmStreamingType FnType = getArmStreamingFnType(FD); - if (FnType == ArmStreaming && BuiltinType == ArmNonStreaming) { S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) << TheCall->getSourceRange() << "streaming"; @@ -3168,9 +3167,77 @@ static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, << TheCall->getSourceRange() << "streaming compatible"; return; } + + if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) { + S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) + << TheCall->getSourceRange() << "non-streaming"; + } +} + +static bool hasSMEZAState(const FunctionDecl *FD) { + if (FD->hasAttr()) + return true; + if (const auto *T = FD->getType()->getAs()) + if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask) + return true; + return false; +} + +static bool hasSMEZAState(unsigned BuiltinID) { + switch (BuiltinID) { + default: + return false; +#define GET_SME_BUILTIN_HAS_ZA_STATE +#include "clang/Basic/arm_sme_builtins_za_state.inc" +#undef GET_SME_BUILTIN_HAS_ZA_STATE + } +} + +bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { + if (const FunctionDecl *FD = getCurFunctionDecl()) { + std::optional BuiltinType; + + switch (BuiltinID) { +#define GET_SME_STREAMING_ATTRS +#include "clang/Basic/arm_sme_streaming_attrs.inc" +#undef GET_SME_STREAMING_ATTRS + } + + if (BuiltinType) + checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType); + + if (hasSMEZAState(BuiltinID) && !hasSMEZAState(FD)) + Diag(TheCall->getBeginLoc(), + diag::warn_attribute_arm_za_builtin_no_za_state) + << TheCall->getSourceRange(); + } + + // Range check SME intrinsics that take immediate values. + SmallVector, 3> ImmChecks; + + switch (BuiltinID) { + default: + return false; +#define GET_SME_IMMEDIATE_CHECK +#include "clang/Basic/arm_sme_sema_rangechecks.inc" +#undef GET_SME_IMMEDIATE_CHECK + } + + return ParseSVEImmChecks(TheCall, ImmChecks); } bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { + if (const FunctionDecl *FD = getCurFunctionDecl()) { + std::optional BuiltinType; + + switch (BuiltinID) { +#define GET_SVE_STREAMING_ATTRS +#include "clang/Basic/arm_sve_streaming_attrs.inc" +#undef GET_SVE_STREAMING_ATTRS + } + if (BuiltinType) + checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType); + } // Range check SVE intrinsics that take immediate values. SmallVector, 3> ImmChecks; @@ -3180,9 +3247,6 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { #define GET_SVE_IMMEDIATE_CHECK #include "clang/Basic/arm_sve_sema_rangechecks.inc" #undef GET_SVE_IMMEDIATE_CHECK -#define GET_SME_IMMEDIATE_CHECK -#include "clang/Basic/arm_sme_sema_rangechecks.inc" -#undef GET_SME_IMMEDIATE_CHECK } return ParseSVEImmChecks(TheCall, ImmChecks); @@ -3569,6 +3633,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, if (CheckSVEBuiltinFunctionCall(BuiltinID, TheCall)) return true; + if (CheckSMEBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + // For intrinsics which take an immediate value as part of the instruction, // range check them here. unsigned i = 0, l = 0, u = 0; @@ -5030,14 +5097,14 @@ bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, if (!llvm::isValidAtomicOrderingCABI(Ord)) return Diag(ArgExpr->getBeginLoc(), diag::warn_atomic_op_has_invalid_memory_order) - << ArgExpr->getSourceRange(); + << 0 << ArgExpr->getSourceRange(); switch (static_cast(Ord)) { case llvm::AtomicOrderingCABI::relaxed: case llvm::AtomicOrderingCABI::consume: if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence) return Diag(ArgExpr->getBeginLoc(), diag::warn_atomic_op_has_invalid_memory_order) - << ArgExpr->getSourceRange(); + << 0 << ArgExpr->getSourceRange(); break; case llvm::AtomicOrderingCABI::acquire: case llvm::AtomicOrderingCABI::release: @@ -5321,15 +5388,17 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, QualType Op1Type = TheCall->getArg(0)->getType(); QualType Op2Type = TheCall->getArg(1)->getType(); QualType Op3Type = TheCall->getArg(2)->getType(); - uint64_t ElemSize = Op1Type->isRVVType(32, false) ? 32 : 64; - if (ElemSize == 64 && !TI.hasFeature("experimental-zvknhb")) - return - Diag(TheCall->getBeginLoc(), diag::err_riscv_type_requires_extension) - << Op1Type << "experimental-zvknhb"; + ASTContext::BuiltinVectorTypeInfo Info = + Context.getBuiltinVectorTypeInfo(Op1Type->castAs()); + uint64_t ElemSize = Context.getTypeSize(Info.ElementType); + if (ElemSize == 64 && !TI.hasFeature("zvknhb")) + return Diag(TheCall->getBeginLoc(), + diag::err_riscv_builtin_requires_extension) + << /* IsExtension */ true << TheCall->getSourceRange() << "zvknb"; - return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, ElemSize << 2) || - CheckInvalidVLENandLMUL(TI, TheCall, *this, Op2Type, ElemSize << 2) || - CheckInvalidVLENandLMUL(TI, TheCall, *this, Op3Type, ElemSize << 2); + return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, ElemSize * 4) || + CheckInvalidVLENandLMUL(TI, TheCall, *this, Op2Type, ElemSize * 4) || + CheckInvalidVLENandLMUL(TI, TheCall, *this, Op3Type, ElemSize * 4); } case RISCVVector::BI__builtin_rvv_sf_vc_i_se_u8mf8: @@ -6103,30 +6172,33 @@ bool Sema::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D) { const TargetInfo &TI = Context.getTargetInfo(); + + ASTContext::BuiltinVectorTypeInfo Info = + Context.getBuiltinVectorTypeInfo(Ty->castAs()); + unsigned EltSize = Context.getTypeSize(Info.ElementType); + unsigned MinElts = Info.EC.getKnownMinValue(); + // (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at // least zve64x - if ((Ty->isRVVType(/* Bitwidth */ 64, /* IsFloat */ false) || - Ty->isRVVType(/* ElementCount */ 1)) && + if (((EltSize == 64 && Info.ElementType->isIntegerType()) || MinElts == 1) && !TI.hasFeature("zve64x")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x"; - if (Ty->isRVVType(/* Bitwidth */ 16, /* IsFloat */ true) && - !TI.hasFeature("zvfh") && !TI.hasFeature("zvfhmin")) + else if (Info.ElementType->isFloat16Type() && !TI.hasFeature("zvfh") && + !TI.hasFeature("zvfhmin")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfh or zvfhmin"; - // Check if enabled zvfbfmin for BFloat16 - if (Ty->isRVVType(/* Bitwidth */ 16, /* IsFloat */ false, - /* IsBFloat */ true) && - !TI.hasFeature("experimental-zvfbfmin")) + else if (Info.ElementType->isBFloat16Type() && + !TI.hasFeature("experimental-zvfbfmin")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin"; - if (Ty->isRVVType(/* Bitwidth */ 32, /* IsFloat */ true) && - !TI.hasFeature("zve32f")) + else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) && + !TI.hasFeature("zve32f")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f"; - if (Ty->isRVVType(/* Bitwidth */ 64, /* IsFloat */ true) && - !TI.hasFeature("zve64d")) + else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Double) && + !TI.hasFeature("zve64d")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64d"; // Given that caller already checked isRVVType() before calling this function, // if we don't have at least zve32x supported, then we need to emit error. - if (!TI.hasFeature("zve32x")) + else if (!TI.hasFeature("zve32x")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x"; } @@ -8177,13 +8249,31 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, break; } + // If the memory orders are constants, check they are valid. if (SubExprs.size() >= 2 && Form != Init) { - if (std::optional Result = - SubExprs[1]->getIntegerConstantExpr(Context)) - if (!isValidOrderingForOp(Result->getSExtValue(), Op)) - Diag(SubExprs[1]->getBeginLoc(), - diag::warn_atomic_op_has_invalid_memory_order) - << SubExprs[1]->getSourceRange(); + std::optional Success = + SubExprs[1]->getIntegerConstantExpr(Context); + if (Success && !isValidOrderingForOp(Success->getSExtValue(), Op)) { + Diag(SubExprs[1]->getBeginLoc(), + diag::warn_atomic_op_has_invalid_memory_order) + << /*success=*/(Form == C11CmpXchg || Form == GNUCmpXchg) + << SubExprs[1]->getSourceRange(); + } + if (SubExprs.size() >= 5) { + if (std::optional Failure = + SubExprs[3]->getIntegerConstantExpr(Context)) { + if (!llvm::is_contained( + {llvm::AtomicOrderingCABI::relaxed, + llvm::AtomicOrderingCABI::consume, + llvm::AtomicOrderingCABI::acquire, + llvm::AtomicOrderingCABI::seq_cst}, + (llvm::AtomicOrderingCABI)Failure->getSExtValue())) { + Diag(SubExprs[3]->getBeginLoc(), + diag::warn_atomic_op_has_invalid_memory_order) + << /*failure=*/2 << SubExprs[3]->getSourceRange(); + } + } + } } if (auto ScopeModel = AtomicExpr::getScopeModel(Op)) { @@ -18270,15 +18360,14 @@ static bool isSetterLikeSelector(Selector sel) { StringRef str = sel.getNameForSlot(0); while (!str.empty() && str.front() == '_') str = str.substr(1); - if (str.startswith("set")) + if (str.starts_with("set")) str = str.substr(3); - else if (str.startswith("add")) { + else if (str.starts_with("add")) { // Specially allow 'addOperationWithBlock:'. - if (sel.getNumArgs() == 1 && str.startswith("addOperationWithBlock")) + if (sel.getNumArgs() == 1 && str.starts_with("addOperationWithBlock")) return false; str = str.substr(3); - } - else + } else return false; if (str.empty()) return true; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 143968b4ab0442fe017705f21dccbef066c164ab..c44be0df9b0a853f2ee2fcb88e59691a5398f27c 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -9798,7 +9798,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector( Results.ExitScope(); if (!AtParameterName && !SelIdents.empty() && - SelIdents.front()->getName().startswith("init")) { + SelIdents.front()->getName().starts_with("init")) { for (const auto &M : PP.macros()) { if (M.first->getName() != "NS_DESIGNATED_INITIALIZER") continue; @@ -10110,7 +10110,7 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) { } const StringRef &Dirname = llvm::sys::path::filename(Dir); - const bool isQt = Dirname.startswith("Qt") || Dirname == "ActiveQt"; + const bool isQt = Dirname.starts_with("Qt") || Dirname == "ActiveQt"; const bool ExtensionlessHeaders = IsSystem || isQt || Dir.ends_with(".framework/Headers"); std::error_code EC; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 19d972ed8ab2d830ec9b099d3a820ff00561bc03..ffbe317d559995359c820064dacc376366c76be8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2005,12 +2005,12 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts, if (D->isInvalidDecl()) return false; - if (auto *DD = dyn_cast(D)) { + if (const auto *DD = dyn_cast(D)) { // For a decomposition declaration, warn if none of the bindings are // referenced, instead of if the variable itself is referenced (which // it is, by the bindings' expressions). bool IsAllPlaceholders = true; - for (auto *BD : DD->bindings()) { + for (const auto *BD : DD->bindings()) { if (BD->isReferenced()) return false; IsAllPlaceholders = IsAllPlaceholders && BD->isPlaceholderVar(LangOpts); @@ -2054,7 +2054,7 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts, if (const VarDecl *VD = dyn_cast(D)) { const Expr *Init = VD->getInit(); - if (const auto *Cleanups = dyn_cast_or_null(Init)) + if (const auto *Cleanups = dyn_cast_if_present(Init)) Init = Cleanups->getSubExpr(); const auto *Ty = VD->getType().getTypePtr(); @@ -2068,11 +2068,10 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts, // Warn for reference variables whose initializtion performs lifetime // extension. - if (const auto *MTE = dyn_cast_or_null(Init)) { - if (MTE->getExtendingDecl()) { - Ty = VD->getType().getNonReferenceType().getTypePtr(); - Init = MTE->getSubExpr()->IgnoreImplicitAsWritten(); - } + if (const auto *MTE = dyn_cast_if_present(Init); + MTE && MTE->getExtendingDecl()) { + Ty = VD->getType().getNonReferenceType().getTypePtr(); + Init = MTE->getSubExpr()->IgnoreImplicitAsWritten(); } // If we failed to complete the type for some reason, or if the type is @@ -2089,15 +2088,14 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts, if (Tag->hasAttr()) return false; - if (const CXXRecordDecl *RD = dyn_cast(Tag)) { + if (const auto *RD = dyn_cast(Tag)) { if (!RD->hasTrivialDestructor() && !RD->hasAttr()) return false; if (Init) { - const CXXConstructExpr *Construct = - dyn_cast(Init); + const auto *Construct = dyn_cast(Init); if (Construct && !Construct->isElidable()) { - CXXConstructorDecl *CD = Construct->getConstructor(); + const CXXConstructorDecl *CD = Construct->getConstructor(); if (!CD->isTrivial() && !RD->hasAttr() && (VD->getInit()->isValueDependent() || !VD->evaluateValue())) return false; @@ -2211,10 +2209,9 @@ void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD, return; // In C++, don't warn for record types that don't have WarnUnusedAttr, to // mimic gcc's behavior. - if (const CXXRecordDecl *RD = dyn_cast(Tag)) { - if (!RD->hasAttr()) - return; - } + if (const auto *RD = dyn_cast(Tag); + RD && !RD->hasAttr()) + return; } // Don't warn about __block Objective-C pointer variables, as they might @@ -12957,7 +12954,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, // FIXME: Initialization should not be taking a mutable list of inits. SmallVector InitsCopy(DeduceInits.begin(), DeduceInits.end()); return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind, - InitsCopy, PL); + InitsCopy); } if (DirectInit) { @@ -15800,7 +15797,7 @@ Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { } Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { - return ActOnFinishFunctionBody(D, BodyArg, false); + return ActOnFinishFunctionBody(D, BodyArg, /*IsInstantiation=*/false); } /// RAII object that pops an ExpressionEvaluationContext when exiting a function @@ -16005,7 +16002,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, return StartTok.consume_front("const") && (StartTok.empty() || isWhitespace(StartTok[0]) || - StartTok.startswith("/*") || StartTok.startswith("//")); + StartTok.starts_with("/*") || StartTok.starts_with("//")); }; auto findBeginLoc = [&]() { @@ -16359,7 +16356,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, // Extension in C99 (defaults to error). Legal in C89, but warn about it. unsigned diag_id; - if (II.getName().startswith("__builtin_")) + if (II.getName().starts_with("__builtin_")) diag_id = diag::warn_builtin_unknown; // OpenCL v2.0 s6.9.u - Implicit function declaration is not supported. else if (getLangOpts().C99) @@ -19518,20 +19515,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, CDecl->setIvarRBraceLoc(RBrac); } } - - // Check the "counted_by" attribute to ensure that the count field exists in - // the struct. Make sure we're performing this check on the outer-most - // record. This is a C-only feature. - if (!getLangOpts().CPlusPlus && Record && - !isa(Record->getParent())) { - auto Pred = [](const Decl *D) { - if (const auto *FD = dyn_cast_if_present(D)) - return FD->hasAttr(); - return false; - }; - if (const FieldDecl *FD = Record->findFieldIf(Pred)) - CheckCountedByAttr(S, FD); - } } /// Determine whether the given integral value is representable within diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 59e456fd9f729837de00d86e5511db839d960c6d..4a385a396fa62beccbe74797eb20bbbd0595b991 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1809,8 +1809,8 @@ static void handleAssumumptionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { /// Normalize the attribute, __foo__ becomes foo. /// Returns true if normalization was applied. static bool normalizeName(StringRef &AttrName) { - if (AttrName.size() > 4 && AttrName.startswith("__") && - AttrName.endswith("__")) { + if (AttrName.size() > 4 && AttrName.starts_with("__") && + AttrName.ends_with("__")) { AttrName = AttrName.drop_front(2).drop_back(2); return true; } @@ -3605,7 +3605,7 @@ bool Sema::checkTargetClonesAttrString( } } else { // Other targets ( currently X86 ) - if (Cur.startswith("arch=")) { + if (Cur.starts_with("arch=")) { if (!Context.getTargetInfo().isValidCPUName( Cur.drop_front(sizeof("arch=") - 1))) return Diag(CurLoc, diag::warn_unsupported_target_attribute) @@ -3623,7 +3623,7 @@ bool Sema::checkTargetClonesAttrString( StringsBuffer.push_back(Cur); } } - if (Str.rtrim().endswith(",")) + if (Str.rtrim().ends_with(",")) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unsupported << None << "" << TargetClones; return false; @@ -5225,8 +5225,16 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!AL.checkAtLeastNumArgs(S, 1)) + if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) { + // Suppression attribute with GSL spelling requires at least 1 argument. + if (!AL.checkAtLeastNumArgs(S, 1)) + return; + } else if (!isa(D)) { + // Analyzer suppression applies only to variables and statements. + S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str) + << AL << 0 << "variables and statements"; return; + } std::vector DiagnosticIdentifiers; for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) { @@ -5235,8 +5243,6 @@ static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr)) return; - // FIXME: Warn if the rule name is unknown. This is tricky because only - // clang-tidy knows about available rules. DiagnosticIdentifiers.push_back(RuleName); } D->addAttr(::new (S.Context) @@ -5819,8 +5825,7 @@ struct IntrinToName { static bool ArmBuiltinAliasValid(unsigned BuiltinID, StringRef AliasName, ArrayRef Map, const char *IntrinNames) { - if (AliasName.startswith("__arm_")) - AliasName = AliasName.substr(6); + AliasName.consume_front("__arm_"); const IntrinToName *It = llvm::lower_bound(Map, BuiltinID, [](const IntrinToName &L, unsigned Id) { return L.Id < Id; @@ -6663,10 +6668,10 @@ validateSwiftFunctionName(Sema &S, const ParsedAttr &AL, SourceLocation Loc, // Check whether this will be mapped to a getter or setter of a property. bool IsGetter = false, IsSetter = false; - if (Name.startswith("getter:")) { + if (Name.starts_with("getter:")) { IsGetter = true; Name = Name.substr(7); - } else if (Name.startswith("setter:")) { + } else if (Name.starts_with("setter:")) { IsSetter = true; Name = Name.substr(7); } @@ -7292,7 +7297,7 @@ static void handleHLSLResourceBindingAttr(Sema &S, Decl *D, } } - if (!Space.startswith("space")) { + if (!Space.starts_with("space")) { S.Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space; return; } @@ -8439,92 +8444,6 @@ static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL)); } -static void handleCountedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!AL.isArgIdent(0)) { - S.Diag(AL.getLoc(), diag::err_attribute_argument_type) - << AL << AANT_ArgumentIdentifier; - return; - } - - IdentifierLoc *IL = AL.getArgAsIdent(0); - CountedByAttr *CBA = - ::new (S.Context) CountedByAttr(S.Context, AL, IL->Ident); - CBA->setCountedByFieldLoc(IL->Loc); - D->addAttr(CBA); -} - -bool Sema::CheckCountedByAttr(Scope *S, const FieldDecl *FD) { - const auto *CBA = FD->getAttr(); - const IdentifierInfo *FieldName = CBA->getCountedByField(); - DeclarationNameInfo NameInfo(FieldName, - CBA->getCountedByFieldLoc().getBegin()); - - LookupResult MemResult(*this, NameInfo, Sema::LookupMemberName); - LookupName(MemResult, S); - - if (MemResult.empty()) { - // The "counted_by" field needs to exist within the struct. - LookupResult OrdResult(*this, NameInfo, Sema::LookupOrdinaryName); - LookupName(OrdResult, S); - - if (!OrdResult.empty()) { - SourceRange SR = FD->getLocation(); - Diag(SR.getBegin(), diag::err_counted_by_must_be_in_structure) - << FieldName << SR; - - if (auto *ND = OrdResult.getAsSingle()) { - SR = ND->getLocation(); - Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field) - << ND << SR; - } - return true; - } - - CXXScopeSpec SS; - DeclFilterCCC Filter(FieldName); - return DiagnoseEmptyLookup(S, SS, MemResult, Filter, nullptr, std::nullopt, - const_cast(FD->getDeclContext())); - } - - LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = - LangOptions::StrictFlexArraysLevelKind::IncompleteOnly; - - if (!Decl::isFlexibleArrayMemberLike(Context, FD, FD->getType(), - StrictFlexArraysLevel, true)) { - // The "counted_by" attribute must be on a flexible array member. - SourceRange SR = FD->getLocation(); - Diag(SR.getBegin(), diag::err_counted_by_attr_not_on_flexible_array_member) - << SR; - return true; - } - - if (const FieldDecl *Field = MemResult.getAsSingle()) { - if (Field->hasAttr()) { - // The "counted_by" field can't point to the flexible array member. - SourceRange SR = CBA->getCountedByFieldLoc(); - Diag(SR.getBegin(), diag::err_counted_by_attr_refers_to_flexible_array) - << CBA->getCountedByField() << SR; - return true; - } - - if (!Field->getType()->isIntegerType() || - Field->getType()->isBooleanType()) { - // The "counted_by" field must have an integer type. - SourceRange SR = CBA->getCountedByFieldLoc(); - Diag(SR.getBegin(), - diag::err_flexible_array_counted_by_attr_field_not_integer) - << CBA->getCountedByField() << SR; - - SR = Field->getLocation(); - Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field) - << Field << SR; - return true; - } - } - - return false; -} - static void handleFunctionReturnThunksAttr(Sema &S, Decl *D, const ParsedAttr &AL) { StringRef KindStr; @@ -9482,10 +9401,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, handleAvailableOnlyInDefaultEvalMethod(S, D, AL); break; - case ParsedAttr::AT_CountedBy: - handleCountedByAttr(S, D, AL); - break; - // Microsoft attributes: case ParsedAttr::AT_LayoutVersion: handleLayoutVersion(S, D, AL); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index cdfa6ad3f281a4359bf4b0da41233a50f1eefa9f..c3b95e168a605166c9f4a3e96f1297cd43ca64e4 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -296,7 +296,7 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, RealizedPlatform = S.Context.getTargetInfo().getPlatformName(); // Warn about implementing unavailable methods, unless the unavailable // is for an app extension. - if (RealizedPlatform.endswith("_app_extension")) + if (RealizedPlatform.ends_with("_app_extension")) return; S.Diag(ImplLoc, diag::warn_unavailable_def); S.Diag(ND->getLocation(), diag::note_method_declared_at) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d629be083d8c38c2da587dd40210f19ee23deb86..960f513d1111b2c71d0b001855106d2a52d02b33 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2469,8 +2469,7 @@ bool Sema::DiagnoseDependentMemberLookup(const LookupResult &R) { bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef Args, DeclContext *LookupCtx, - TypoExpr **Out) { + ArrayRef Args, TypoExpr **Out) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -2486,8 +2485,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // unqualified lookup. This is useful when (for example) the // original lookup would not have found something because it was a // dependent name. - DeclContext *DC = - LookupCtx ? LookupCtx : (SS.isEmpty() ? CurContext : nullptr); + DeclContext *DC = SS.isEmpty() ? CurContext : nullptr; while (DC) { if (isa(DC)) { LookupQualifiedName(R, DC); @@ -2530,12 +2528,12 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args, diagnostic, diagnostic_suggest); }, - nullptr, CTK_ErrorRecovery, LookupCtx); + nullptr, CTK_ErrorRecovery); if (*Out) return true; - } else if (S && (Corrected = - CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, - &SS, CCC, CTK_ErrorRecovery, LookupCtx))) { + } else if (S && + (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), + S, &SS, CCC, CTK_ErrorRecovery))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; @@ -2825,7 +2823,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // a template name, but we happen to have always already looked up the name // before we get here if it must be a template name. if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator, nullptr, - std::nullopt, nullptr, &TE)) { + std::nullopt, &TE)) { if (TE && KeywordReplacement) { auto &State = getTypoExprState(TE); auto BestTC = State.Consumer->getNextCorrection(); @@ -13808,12 +13806,12 @@ static void diagnoseXorMisusedAsPow(Sema &S, const ExprResult &XorLHS, StringRef RHSStrRef = RHSStr; // Do not diagnose literals with digit separators, binary, hexadecimal, octal // literals. - if (LHSStrRef.startswith("0b") || LHSStrRef.startswith("0B") || - RHSStrRef.startswith("0b") || RHSStrRef.startswith("0B") || - LHSStrRef.startswith("0x") || LHSStrRef.startswith("0X") || - RHSStrRef.startswith("0x") || RHSStrRef.startswith("0X") || - (LHSStrRef.size() > 1 && LHSStrRef.startswith("0")) || - (RHSStrRef.size() > 1 && RHSStrRef.startswith("0")) || + if (LHSStrRef.starts_with("0b") || LHSStrRef.starts_with("0B") || + RHSStrRef.starts_with("0b") || RHSStrRef.starts_with("0B") || + LHSStrRef.starts_with("0x") || LHSStrRef.starts_with("0X") || + RHSStrRef.starts_with("0x") || RHSStrRef.starts_with("0X") || + (LHSStrRef.size() > 1 && LHSStrRef.starts_with("0")) || + (RHSStrRef.size() > 1 && RHSStrRef.starts_with("0")) || LHSStrRef.contains('\'') || RHSStrRef.contains('\'')) return; @@ -15508,7 +15506,7 @@ static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R, if (const ObjCMessageExpr *ME = dyn_cast(Ex)) { Selector S = ME->getSelector(); StringRef SelArg0 = S.getNameForSlot(0); - if (SelArg0.startswith("performSelector")) + if (SelArg0.starts_with("performSelector")) Diag = diag::warn_objc_pointer_masking_performSelector; } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 081b568762ae228827b47dcef0ef8d9b583bdf46..4ae04358d5df7c811eabe771a9b7b1fb3adb7325 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -843,21 +843,21 @@ Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) { // operation from the operand to the exception object (15.1) can be // omitted by constructing the automatic object directly into the // exception object - if (DeclRefExpr *DRE = dyn_cast(Ex->IgnoreParens())) - if (VarDecl *Var = dyn_cast(DRE->getDecl())) { - if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) { - for( ; S; S = S->getParent()) { - if (S->isDeclScope(Var)) { - IsThrownVarInScope = true; - break; - } - - // FIXME: Many of the scope checks here seem incorrect. - if (S->getFlags() & - (Scope::FnScope | Scope::ClassScope | Scope::BlockScope | - Scope::ObjCMethodScope | Scope::TryScope)) - break; + if (const auto *DRE = dyn_cast(Ex->IgnoreParens())) + if (const auto *Var = dyn_cast(DRE->getDecl()); + Var && Var->hasLocalStorage() && + !Var->getType().isVolatileQualified()) { + for (; S; S = S->getParent()) { + if (S->isDeclScope(Var)) { + IsThrownVarInScope = true; + break; } + + // FIXME: Many of the scope checks here seem incorrect. + if (S->getFlags() & + (Scope::FnScope | Scope::ClassScope | Scope::BlockScope | + Scope::ObjCMethodScope | Scope::TryScope)) + break; } } } diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 473eea55bb6b19e026dd39749bbeb5ad10cccc32..2abec3d86a27d99927210119ea588c53b56c3666 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -253,7 +253,9 @@ static void diagnoseInstanceReference(Sema &SemaRef, SemaRef.Diag(Loc, diag::err_member_call_without_object) << Range << /*static*/ 0; else { - const auto *Callee = dyn_cast(Rep); + if (const auto *Tpl = dyn_cast(Rep)) + Rep = Tpl->getTemplatedDecl(); + const auto *Callee = cast(Rep); auto Diag = SemaRef.Diag(Loc, diag::err_member_call_without_object) << Range << Callee->isExplicitObjectMemberFunction(); if (!Replacement.empty()) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 5ca6b232df66a560b97751c73f3c6ff87cb978d5..cc9db5ded1149a0ec053214121af72fdc4d6d158 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -25,6 +25,7 @@ #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/Ownership.h" #include "clang/Sema/SemaInternal.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/FoldingSet.h" @@ -4414,7 +4415,8 @@ static void TryReferenceInitializationCore(Sema &S, Qualifiers T1Quals, QualType cv2T2, QualType T2, Qualifiers T2Quals, - InitializationSequence &Sequence); + InitializationSequence &Sequence, + bool TopLevelOfInitList); static void TryValueInitialization(Sema &S, const InitializedEntity &Entity, @@ -4468,7 +4470,8 @@ static void TryReferenceListInitialization(Sema &S, if (RefRelationship >= Sema::Ref_Related) { // Try to bind the reference here. TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1, - T1Quals, cv2T2, T2, T2Quals, Sequence); + T1Quals, cv2T2, T2, T2Quals, Sequence, + /*TopLevelOfInitList=*/true); if (Sequence) Sequence.RewrapReferenceInitList(cv1T1, InitList); return; @@ -4927,11 +4930,11 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, Expr *CurInitExpr); /// Attempt reference initialization (C++0x [dcl.init.ref]) -static void TryReferenceInitialization(Sema &S, - const InitializedEntity &Entity, +static void TryReferenceInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr *Initializer, - InitializationSequence &Sequence) { + InitializationSequence &Sequence, + bool TopLevelOfInitList) { QualType DestType = Entity.getType(); QualType cv1T1 = DestType->castAs()->getPointeeType(); Qualifiers T1Quals; @@ -4949,7 +4952,8 @@ static void TryReferenceInitialization(Sema &S, // Delegate everything else to a subfunction. TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1, - T1Quals, cv2T2, T2, T2Quals, Sequence); + T1Quals, cv2T2, T2, T2Quals, Sequence, + TopLevelOfInitList); } /// Determine whether an expression is a non-referenceable glvalue (one to @@ -4972,7 +4976,8 @@ static void TryReferenceInitializationCore(Sema &S, Qualifiers T1Quals, QualType cv2T2, QualType T2, Qualifiers T2Quals, - InitializationSequence &Sequence) { + InitializationSequence &Sequence, + bool TopLevelOfInitList) { QualType DestType = Entity.getType(); SourceLocation DeclLoc = Initializer->getBeginLoc(); @@ -5246,7 +5251,8 @@ static void TryReferenceInitializationCore(Sema &S, Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed); return; } else { - Sequence.AddConversionSequenceStep(ICS, TempEntity.getType()); + Sequence.AddConversionSequenceStep(ICS, TempEntity.getType(), + TopLevelOfInitList); } // [...] If T1 is reference-related to T2, cv1 must be the @@ -5424,18 +5430,12 @@ static void TryOrBuildParenListInitialization( auto HandleInitializedEntity = [&](const InitializedEntity &SubEntity, const InitializationKind &SubKind, Expr *Arg, Expr **InitExpr = nullptr) { - InitializationSequence IS = [&]() { - if (Arg) - return InitializationSequence(S, SubEntity, SubKind, Arg); - return InitializationSequence(S, SubEntity, SubKind, std::nullopt); - }(); + InitializationSequence IS = InitializationSequence( + S, SubEntity, SubKind, Arg ? MultiExprArg(Arg) : std::nullopt); if (IS.Failed()) { if (!VerifyOnly) { - if (Arg) - IS.Diagnose(S, SubEntity, SubKind, Arg); - else - IS.Diagnose(S, SubEntity, SubKind, std::nullopt); + IS.Diagnose(S, SubEntity, SubKind, Arg ? ArrayRef(Arg) : std::nullopt); } else { Sequence.SetFailed( InitializationSequence::FK_ParenthesizedListInitFailed); @@ -5445,10 +5445,8 @@ static void TryOrBuildParenListInitialization( } if (!VerifyOnly) { ExprResult ER; - if (Arg) - ER = IS.Perform(S, SubEntity, SubKind, Arg); - else - ER = IS.Perform(S, SubEntity, SubKind, std::nullopt); + ER = IS.Perform(S, SubEntity, SubKind, + Arg ? MultiExprArg(Arg) : std::nullopt); if (InitExpr) *InitExpr = ER.get(); else @@ -5514,6 +5512,14 @@ static void TryOrBuildParenListInitialization( } else if (auto *RT = Entity.getType()->getAs()) { bool IsUnion = RT->isUnionType(); const CXXRecordDecl *RD = cast(RT->getDecl()); + if (RD->isInvalidDecl()) { + // Exit early to avoid confusion when processing members. + // We do the same for braced list initialization in + // `CheckStructUnionTypes`. + Sequence.SetFailed( + clang::InitializationSequence::FK_ParenthesizedListInitFailed); + return; + } if (!IsUnion) { for (const CXXBaseSpecifier &Base : RD->bases()) { @@ -6210,7 +6216,8 @@ void InitializationSequence::InitializeFrom(Sema &S, else if (isa(Args[0])) SetFailed(FK_ParenthesizedListInitForReference); else - TryReferenceInitialization(S, Entity, Kind, Args[0], *this); + TryReferenceInitialization(S, Entity, Kind, Args[0], *this, + TopLevelOfInitList); return; } @@ -10404,40 +10411,53 @@ static void DiagnoseNarrowingInInitList(Sema &S, // No narrowing occurred. return; - case NK_Type_Narrowing: + case NK_Type_Narrowing: { // This was a floating-to-integer conversion, which is always considered a // narrowing conversion even if the value is a constant and can be // represented exactly as an integer. - S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts()) - ? diag::ext_init_list_type_narrowing - : diag::warn_init_list_type_narrowing) + QualType T = EntityType.getNonReferenceType(); + S.Diag(PostInit->getBeginLoc(), + NarrowingErrs(S.getLangOpts()) + ? (T == EntityType + ? diag::ext_init_list_type_narrowing + : diag::ext_init_list_type_narrowing_const_reference) + : diag::warn_init_list_type_narrowing) << PostInit->getSourceRange() << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType(); + << T.getLocalUnqualifiedType(); break; + } - case NK_Constant_Narrowing: + case NK_Constant_Narrowing: { // A constant value was narrowed. + QualType T = EntityType.getNonReferenceType(); S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts()) - ? diag::ext_init_list_constant_narrowing + ? (T == EntityType + ? diag::ext_init_list_constant_narrowing + : diag::ext_init_list_constant_narrowing_const_reference) : diag::warn_init_list_constant_narrowing) << PostInit->getSourceRange() << ConstantValue.getAsString(S.getASTContext(), ConstantType) - << EntityType.getLocalUnqualifiedType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; + } - case NK_Variable_Narrowing: + case NK_Variable_Narrowing: { // A variable's value may have been narrowed. + QualType T = EntityType.getNonReferenceType(); S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts()) - ? diag::ext_init_list_variable_narrowing + ? (T == EntityType + ? diag::ext_init_list_variable_narrowing + : diag::ext_init_list_variable_narrowing_const_reference) : diag::warn_init_list_variable_narrowing) << PostInit->getSourceRange() << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; } + } SmallString<128> StaticCast; llvm::raw_svector_ostream OS(StaticCast); @@ -10555,7 +10575,7 @@ static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD, QualType Sema::DeduceTemplateSpecializationFromInitializer( TypeSourceInfo *TSInfo, const InitializedEntity &Entity, - const InitializationKind &Kind, MultiExprArg Inits, ParenListExpr *PL) { + const InitializationKind &Kind, MultiExprArg Inits) { auto *DeducedTST = dyn_cast( TSInfo->getType()->getContainedDeducedType()); assert(DeducedTST && "not a deduced template specialization type"); @@ -10786,9 +10806,12 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (getLangOpts().CPlusPlus20 && !HasAnyDeductionGuide) { if (ListInit && ListInit->getNumInits()) { SynthesizeAggrGuide(ListInit); - } else if (PL && PL->getNumExprs()) { - InitListExpr TempListInit(getASTContext(), PL->getLParenLoc(), - PL->exprs(), PL->getRParenLoc()); + } else if (Inits.size()) { // parenthesized expression-list + // Inits are expressions inside the parentheses. We don't have + // the parentheses source locations, use the begin/end of Inits as the + // best heuristic. + InitListExpr TempListInit(getASTContext(), Inits.front()->getBeginLoc(), + Inits, Inits.back()->getEndLoc()); SynthesizeAggrGuide(&TempListInit); } } diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index 9282ceb8dee03de050315306ade7710f0f40f97d..ed7f626971f345ea9a80420fa334f2b05d7eef6b 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -268,7 +268,7 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, StringRef FirstComponentName = Path[0].first->getName(); if (!getSourceManager().isInSystemHeader(Path[0].second) && (FirstComponentName == "std" || - (FirstComponentName.startswith("std") && + (FirstComponentName.starts_with("std") && llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit)))) Diag(Path[0].second, diag::warn_reserved_module_name) << Path[0].first; @@ -529,7 +529,8 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, if (!Mod) return true; - if (!Mod->isInterfaceOrPartition() && !ModuleName.empty()) { + if (!Mod->isInterfaceOrPartition() && !ModuleName.empty() && + !getLangOpts().ObjC) { Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition) << ModuleName; return true; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e400f248d15aa3497b9513603646803f1fb961cb..f34d2959dc619143cb7e2987947af6d4baba42ea 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -12683,7 +12683,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, break; } case OMPC_fail: { - if (AtomicKind != OMPC_compare) { + if (!EncounteredAtomicKinds.contains(OMPC_compare)) { Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare) << SourceRange(C->getBeginLoc(), C->getEndLoc()); return StmtError(); @@ -14658,6 +14658,19 @@ StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef Clauses, } setFunctionHasBranchProtectedScope(); + const OMPClause *BareClause = nullptr; + bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) && + hasClauses(Clauses, OMPC_thread_limit); + bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) { + BareClause = C; + return C->getClauseKind() == OMPC_ompx_bare; + }); + + if (HasBareClause && !HasThreadLimitAndNumTeamsClause) { + Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid); + return StmtError(); + } + return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); } diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp index 0d411fca0f9c8275489fb476c1850714f49d5b44..3ed3e6195441893f526853cbb315f7c16ef41240 100644 --- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -43,7 +43,7 @@ struct RVVIntrinsicDef { struct RVVOverloadIntrinsicDef { // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList. - SmallVector Indexes; + SmallVector Indexes; }; } // namespace @@ -162,7 +162,7 @@ private: // List of all RVV intrinsic. std::vector IntrinsicList; // Mapping function name to index of IntrinsicList. - StringMap Intrinsics; + StringMap Intrinsics; // Mapping function name to RVVOverloadIntrinsicDef. StringMap OverloadIntrinsics; @@ -174,7 +174,7 @@ private: // Create FunctionDecl for a vector intrinsic. void CreateRVVIntrinsicDecl(LookupResult &LR, IdentifierInfo *II, - Preprocessor &PP, unsigned Index, + Preprocessor &PP, uint32_t Index, bool IsOverload); void ConstructRVVIntrinsics(ArrayRef Recs, @@ -206,15 +206,16 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics( {"xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq}, {"xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod}, {"xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq}, - {"experimental-zvbb", RVV_REQ_Zvbb}, - {"experimental-zvbc", RVV_REQ_Zvbc}, - {"experimental-zvkb", RVV_REQ_Zvkb}, - {"experimental-zvkg", RVV_REQ_Zvkg}, - {"experimental-zvkned", RVV_REQ_Zvkned}, - {"experimental-zvknha", RVV_REQ_Zvknha}, - {"experimental-zvknhb", RVV_REQ_Zvknhb}, - {"experimental-zvksed", RVV_REQ_Zvksed}, - {"experimental-zvksh", RVV_REQ_Zvksh}}; + {"zvbb", RVV_REQ_Zvbb}, + {"zvbc", RVV_REQ_Zvbc}, + {"zvkb", RVV_REQ_Zvkb}, + {"zvkg", RVV_REQ_Zvkg}, + {"zvkned", RVV_REQ_Zvkned}, + {"zvknha", RVV_REQ_Zvknha}, + {"zvknhb", RVV_REQ_Zvknhb}, + {"zvksed", RVV_REQ_Zvksed}, + {"zvksh", RVV_REQ_Zvksh}, + {"experimental", RVV_REQ_Experimental}}; // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics // in RISCVVEmitter.cpp. @@ -386,7 +387,7 @@ void RISCVIntrinsicManagerImpl::InitRVVIntrinsic( Record.HasFRMRoundModeOp); // Put into IntrinsicList. - size_t Index = IntrinsicList.size(); + uint32_t Index = IntrinsicList.size(); IntrinsicList.push_back({BuiltinName, Signature}); // Creating mapping to Intrinsics. @@ -403,7 +404,7 @@ void RISCVIntrinsicManagerImpl::InitRVVIntrinsic( void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR, IdentifierInfo *II, Preprocessor &PP, - unsigned Index, + uint32_t Index, bool IsOverload) { ASTContext &Context = S.Context; RVVIntrinsicDef &IDef = IntrinsicList[Index]; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 63348d27a8c94a1b4a24cb6fe4c4a4607a1655f9..f0b03db690843a4219f02008aa8c57e8be94eb03 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1271,6 +1271,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, bool CaseListIsErroneous = false; + // FIXME: We'd better diagnose missing or duplicate default labels even + // in the dependent case. Because default labels themselves are never + // dependent. for (SwitchCase *SC = SS->getSwitchCaseList(); SC && !HasDependentValue; SC = SC->getNextSwitchCase()) { @@ -1327,9 +1330,6 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, } } - if (!TheDefaultStmt) - Diag(SwitchLoc, diag::warn_switch_default); - if (!HasDependentValue) { // If we don't have a default statement, check whether the // condition is constant. @@ -1344,6 +1344,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, assert(!HasConstantCond || (ConstantCondValue.getBitWidth() == CondWidth && ConstantCondValue.isSigned() == CondIsSigned)); + Diag(SwitchLoc, diag::warn_switch_default); } bool ShouldCheckConstantCond = HasConstantCond; diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 725d8efe3828d659dbbeb58b91571a1453db50c3..e6a4d3e63e4aa87e7173e1e3fc01dd5e3bf74fef 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -53,6 +53,13 @@ static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const ParsedAttr &A, static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { + if (A.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress && + A.getNumArgs() < 1) { + // Suppression attribute with GSL spelling requires at least 1 argument. + S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments) << A << 1; + return nullptr; + } + std::vector DiagnosticIdentifiers; for (unsigned I = 0, E = A.getNumArgs(); I != E; ++I) { StringRef RuleName; @@ -60,8 +67,6 @@ static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A, if (!S.checkStringLiteralArgumentAttr(A, I, RuleName, nullptr)) return nullptr; - // FIXME: Warn if the rule name is unknown. This is tricky because only - // clang-tidy knows about available rules. DiagnosticIdentifiers.push_back(RuleName); } @@ -356,11 +361,10 @@ static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) { } // Diagnose non-identical duplicates as a 'conflicting' loop attributes -// and suppress duplicate errors in cases where the two match for -// [[clang::code_align()]] attribute. -static void CheckForDuplicateCodeAlignAttrs(Sema &S, - ArrayRef Attrs) { - auto FindFunc = [](const Attr *A) { return isa(A); }; +// and suppress duplicate errors in cases where the two match. +template +static void CheckForDuplicateLoopAttrs(Sema &S, ArrayRef Attrs) { + auto FindFunc = [](const Attr *A) { return isa(A); }; const auto *FirstItr = std::find_if(Attrs.begin(), Attrs.end(), FindFunc); if (FirstItr == Attrs.end()) // no attributes found @@ -370,7 +374,7 @@ static void CheckForDuplicateCodeAlignAttrs(Sema &S, std::optional FirstValue; const auto *CAFA = - dyn_cast(cast(*FirstItr)->getAlignment()); + dyn_cast(cast(*FirstItr)->getAlignment()); // Return early if first alignment expression is dependent (since we don't // know what the effective size will be), and skip the loop entirely. if (!CAFA) @@ -378,8 +382,8 @@ static void CheckForDuplicateCodeAlignAttrs(Sema &S, while (Attrs.end() != (LastFoundItr = std::find_if(LastFoundItr + 1, Attrs.end(), FindFunc))) { - const auto *CASA = dyn_cast( - cast(*LastFoundItr)->getAlignment()); + const auto *CASA = + dyn_cast(cast(*LastFoundItr)->getAlignment()); // If the value is dependent, we can not test anything. if (!CASA) return; @@ -630,10 +634,10 @@ void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs, } CheckForIncompatibleAttributes(*this, OutAttrs); - CheckForDuplicateCodeAlignAttrs(*this, OutAttrs); + CheckForDuplicateLoopAttrs(*this, OutAttrs); } -bool Sema::CheckRebuiltCodeAlignStmtAttributes(ArrayRef Attrs) { - CheckForDuplicateCodeAlignAttrs(*this, Attrs); +bool Sema::CheckRebuiltStmtAttributes(ArrayRef Attrs) { + CheckForDuplicateLoopAttrs(*this, Attrs); return false; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index f10abeaba0d4517ed5df60d4fbaae7919b7d829a..5fcc39ec700522837a8a2415964b730b737b8d16 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1824,6 +1824,15 @@ static void SetNestedNameSpecifier(Sema &S, TagDecl *T, T->setQualifierInfo(SS.getWithLocInContext(S.Context)); } +// Returns the template parameter list with all default template argument +// information. +static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) { + // Make sure we get the template parameter list from the most + // recent declaration, since that is the only one that is guaranteed to + // have all the default template argument information. + return cast(TD->getMostRecentDecl())->getTemplateParameters(); +} + DeclResult Sema::CheckClassTemplate( Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, @@ -2061,13 +2070,13 @@ DeclResult Sema::CheckClassTemplate( if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && CheckTemplateParameterList( TemplateParams, - PrevClassTemplate - ? PrevClassTemplate->getMostRecentDecl()->getTemplateParameters() - : nullptr, + PrevClassTemplate ? GetTemplateParameterList(PrevClassTemplate) + : nullptr, (SS.isSet() && SemanticContext && SemanticContext->isRecord() && SemanticContext->isDependentContext()) ? TPC_ClassTemplateMember - : TUK == TUK_Friend ? TPC_FriendClassTemplate : TPC_ClassTemplate, + : TUK == TUK_Friend ? TPC_FriendClassTemplate + : TPC_ClassTemplate, SkipBody)) Invalid = true; @@ -2298,7 +2307,7 @@ struct ConvertConstructorToDeductionGuideTransform { // -- The template parameters are the template parameters of the class // template followed by the template parameters (including default // template arguments) of the constructor, if any. - TemplateParameterList *TemplateParams = Template->getTemplateParameters(); + TemplateParameterList *TemplateParams = GetTemplateParameterList(Template); if (FTD) { TemplateParameterList *InnerParams = FTD->getTemplateParameters(); SmallVector AllParams; @@ -2424,7 +2433,7 @@ struct ConvertConstructorToDeductionGuideTransform { Params.push_back(NewParam); } - return buildDeductionGuide(Template->getTemplateParameters(), nullptr, + return buildDeductionGuide(GetTemplateParameterList(Template), nullptr, ExplicitSpecifier(), TSI, Loc, Loc, Loc); } @@ -5956,12 +5965,7 @@ bool Sema::CheckTemplateArgumentList( // template. TemplateArgumentListInfo NewArgs = TemplateArgs; - // Make sure we get the template parameter list from the most - // recent declaration, since that is the only one that is guaranteed to - // have all the default template argument information. - TemplateParameterList *Params = - cast(Template->getMostRecentDecl()) - ->getTemplateParameters(); + TemplateParameterList *Params = GetTemplateParameterList(Template); SourceLocation RAngleLoc = NewArgs.getRAngleLoc(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 83610503ed9b16b12089c54dc5e8766ef5272bbc..a376f20fa4f4e08540b3a86ac5a9ac1e96f88b6d 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5371,7 +5371,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, !(D.getIdentifier() && ((D.getIdentifier()->getName() == "printf" && LangOpts.getOpenCLCompatibleVersion() >= 120) || - D.getIdentifier()->getName().startswith("__")))) { + D.getIdentifier()->getName().starts_with("__")))) { S.Diag(D.getIdentifierLoc(), diag::err_opencl_variadic_function); D.setInvalidType(true); } @@ -8360,12 +8360,25 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, // not to need a separate attribute) if (!(S.Context.getTargetInfo().hasFeature("neon") || S.Context.getTargetInfo().hasFeature("mve") || - IsTargetCUDAAndHostARM)) { + S.Context.getTargetInfo().hasFeature("sve") || + S.Context.getTargetInfo().hasFeature("sme") || + IsTargetCUDAAndHostARM) && + VecKind == VectorKind::Neon) { + S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) + << Attr << "'neon', 'mve', 'sve' or 'sme'"; + Attr.setInvalid(); + return; + } + if (!(S.Context.getTargetInfo().hasFeature("neon") || + S.Context.getTargetInfo().hasFeature("mve") || + IsTargetCUDAAndHostARM) && + VecKind == VectorKind::NeonPoly) { S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr << "'neon' or 'mve'"; Attr.setInvalid(); return; } + // Check the attribute arguments. if (Attr.getNumArgs() != 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 1ad843d0bf4e0c3ccc11ed9c1e681b37ba75362a..7df5bf0cb71370b5e43cf9ba3431b2bd7ebaa58c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1378,7 +1378,7 @@ public: StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, ArrayRef Attrs, Stmt *SubStmt) { - if (SemaRef.CheckRebuiltCodeAlignStmtAttributes(Attrs)) + if (SemaRef.CheckRebuiltStmtAttributes(Attrs)) return StmtError(); return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5b51ac40000d7a9894a25c3d7c2727f73dc4348a..9effd333daccdb2061e2e7c52929984dd3d32407 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1781,26 +1781,26 @@ llvm::Error ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, } } -Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, +Token ASTReader::ReadToken(ModuleFile &M, const RecordDataImpl &Record, unsigned &Idx) { Token Tok; Tok.startToken(); - Tok.setLocation(ReadSourceLocation(F, Record, Idx)); + Tok.setLocation(ReadSourceLocation(M, Record, Idx)); Tok.setKind((tok::TokenKind)Record[Idx++]); Tok.setFlag((Token::TokenFlags)Record[Idx++]); if (Tok.isAnnotation()) { - Tok.setAnnotationEndLoc(ReadSourceLocation(F, Record, Idx)); + Tok.setAnnotationEndLoc(ReadSourceLocation(M, Record, Idx)); switch (Tok.getKind()) { case tok::annot_pragma_loop_hint: { auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; - Info->PragmaName = ReadToken(F, Record, Idx); - Info->Option = ReadToken(F, Record, Idx); + Info->PragmaName = ReadToken(M, Record, Idx); + Info->Option = ReadToken(M, Record, Idx); unsigned NumTokens = Record[Idx++]; SmallVector Toks; Toks.reserve(NumTokens); for (unsigned I = 0; I < NumTokens; ++I) - Toks.push_back(ReadToken(F, Record, Idx)); + Toks.push_back(ReadToken(M, Record, Idx)); Info->Toks = llvm::ArrayRef(Toks).copy(PP.getPreprocessorAllocator()); Tok.setAnnotationValue(static_cast(Info)); break; @@ -1811,7 +1811,7 @@ Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, auto SlotLabel = ReadString(Record, Idx); Info->SlotLabel = llvm::StringRef(SlotLabel).copy(PP.getPreprocessorAllocator()); - Info->Alignment = ReadToken(F, Record, Idx); + Info->Alignment = ReadToken(M, Record, Idx); Tok.setAnnotationValue(static_cast(Info)); break; } @@ -1827,7 +1827,7 @@ Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, } } else { Tok.setLength(Record[Idx++]); - if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++])) + if (IdentifierInfo *II = getLocalIdentifier(M, Record[Idx++])) Tok.setIdentifierInfo(II); } return Tok; @@ -1997,10 +1997,10 @@ unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { } HeaderFileInfoTrait::internal_key_type -HeaderFileInfoTrait::GetInternalKey(external_key_type FE) { - internal_key_type ikey = {FE.getSize(), - M.HasTimestamps ? FE.getModificationTime() : 0, - FE.getName(), /*Imported*/ false}; +HeaderFileInfoTrait::GetInternalKey(external_key_type ekey) { + internal_key_type ikey = {ekey.getSize(), + M.HasTimestamps ? ekey.getModificationTime() : 0, + ekey.getName(), /*Imported*/ false}; return ikey; } @@ -8946,10 +8946,10 @@ Module *ASTReader::getModule(unsigned ID) { return getSubmodule(ID); } -ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &F, unsigned ID) { +ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) { if (ID & 1) { // It's a module, look it up by submodule ID. - auto I = GlobalSubmoduleMap.find(getGlobalSubmoduleID(F, ID >> 1)); + auto I = GlobalSubmoduleMap.find(getGlobalSubmoduleID(M, ID >> 1)); return I == GlobalSubmoduleMap.end() ? nullptr : I->second; } else { // It's a prefix (preamble, PCH, ...). Look it up by index. @@ -8959,19 +8959,19 @@ ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &F, unsigned ID) { } } -unsigned ASTReader::getModuleFileID(ModuleFile *F) { - if (!F) +unsigned ASTReader::getModuleFileID(ModuleFile *M) { + if (!M) return 1; // For a file representing a module, use the submodule ID of the top-level // module as the file ID. For any other kind of file, the number of such // files loaded beforehand will be the same on reload. // FIXME: Is this true even if we have an explicit module file and a PCH? - if (F->isModule()) - return ((F->BaseSubmoduleID + NUM_PREDEF_SUBMODULE_IDS) << 1) | 1; + if (M->isModule()) + return ((M->BaseSubmoduleID + NUM_PREDEF_SUBMODULE_IDS) << 1) | 1; auto PCHModules = getModuleManager().pch_modules(); - auto I = llvm::find(PCHModules, F); + auto I = llvm::find(PCHModules, M); assert(I != PCHModules.end() && "emitting reference to unknown file"); return (I - PCHModules.end()) << 1; } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7140a14aefbf9b188f70145a30258342eacc9bb1..547eb77930b4eec86544a285684d581dd98d6cb6 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -584,7 +584,18 @@ void ASTDeclReader::Visit(Decl *D) { void ASTDeclReader::VisitDecl(Decl *D) { BitsUnpacker DeclBits(Record.readInt()); + auto ModuleOwnership = + (Decl::ModuleOwnershipKind)DeclBits.getNextBits(/*Width=*/3); + D->setReferenced(DeclBits.getNextBit()); + D->Used = DeclBits.getNextBit(); + IsDeclMarkedUsed |= D->Used; + D->setAccess((AccessSpecifier)DeclBits.getNextBits(/*Width=*/2)); + D->setImplicit(DeclBits.getNextBit()); bool HasStandaloneLexicalDC = DeclBits.getNextBit(); + bool HasAttrs = DeclBits.getNextBit(); + D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit()); + D->InvalidDecl = DeclBits.getNextBit(); + D->FromASTFile = true; if (D->isTemplateParameter() || D->isTemplateParameterPack() || isa(D)) { @@ -623,20 +634,6 @@ void ASTDeclReader::VisitDecl(Decl *D) { } D->setLocation(ThisDeclLoc); - D->InvalidDecl = DeclBits.getNextBit(); - bool HasAttrs = DeclBits.getNextBit(); - D->setImplicit(DeclBits.getNextBit()); - D->Used = DeclBits.getNextBit(); - IsDeclMarkedUsed |= D->Used; - D->setReferenced(DeclBits.getNextBit()); - D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit()); - D->setAccess((AccessSpecifier)DeclBits.getNextBits(/*Width=*/2)); - D->FromASTFile = true; - auto ModuleOwnership = - (Decl::ModuleOwnershipKind)DeclBits.getNextBits(/*Width=*/3); - bool ModulePrivate = - (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate); - if (HasAttrs) { AttrVec Attrs; Record.readAttributes(Attrs); @@ -647,8 +644,9 @@ void ASTDeclReader::VisitDecl(Decl *D) { // Determine whether this declaration is part of a (sub)module. If so, it // may not yet be visible. + bool ModulePrivate = + (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate); if (unsigned SubmoduleID = readSubmoduleID()) { - switch (ModuleOwnership) { case Decl::ModuleOwnershipKind::Visible: ModuleOwnership = Decl::ModuleOwnershipKind::VisibleWhenImported; @@ -1065,9 +1063,11 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // after everything else is read. BitsUnpacker FunctionDeclBits(Record.readInt()); + FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3)); FD->setStorageClass((StorageClass)FunctionDeclBits.getNextBits(/*Width=*/3)); FD->setInlineSpecified(FunctionDeclBits.getNextBit()); FD->setImplicitlyInline(FunctionDeclBits.getNextBit()); + FD->setHasSkippedBody(FunctionDeclBits.getNextBit()); FD->setVirtualAsWritten(FunctionDeclBits.getNextBit()); // We defer calling `FunctionDecl::setPure()` here as for methods of // `CXXTemplateSpecializationDecl`s, we may not have connected up the @@ -1081,16 +1081,14 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setDefaulted(FunctionDeclBits.getNextBit()); FD->setExplicitlyDefaulted(FunctionDeclBits.getNextBit()); FD->setIneligibleOrNotSelected(FunctionDeclBits.getNextBit()); - FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit()); FD->setConstexprKind( (ConstexprSpecKind)FunctionDeclBits.getNextBits(/*Width=*/2)); - FD->setUsesSEHTry(FunctionDeclBits.getNextBit()); - FD->setHasSkippedBody(FunctionDeclBits.getNextBit()); + FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit()); FD->setIsMultiVersion(FunctionDeclBits.getNextBit()); FD->setLateTemplateParsed(FunctionDeclBits.getNextBit()); FD->setFriendConstraintRefersToEnclosingTemplate( FunctionDeclBits.getNextBit()); - FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3)); + FD->setUsesSEHTry(FunctionDeclBits.getNextBit()); FD->EndRangeLoc = readSourceLocation(); if (FD->isExplicitlyDefaulted()) @@ -1597,6 +1595,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VisitDeclaratorDecl(VD); BitsUnpacker VarDeclBits(Record.readInt()); + auto VarLinkage = Linkage(VarDeclBits.getNextBits(/*Width=*/3)); + bool DefGeneratedInModule = VarDeclBits.getNextBit(); VD->VarDeclBits.SClass = (StorageClass)VarDeclBits.getNextBits(/*Width=*/3); VD->VarDeclBits.TSCSpec = VarDeclBits.getNextBits(/*Width=*/2); VD->VarDeclBits.InitStyle = VarDeclBits.getNextBits(/*Width=*/2); @@ -1608,17 +1608,20 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->NonParmVarDeclBits.ExceptionVar = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.NRVOVariable = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.CXXForRangeDecl = VarDeclBits.getNextBit(); - VD->NonParmVarDeclBits.ObjCForDecl = VarDeclBits.getNextBit(); + VD->NonParmVarDeclBits.IsInline = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.IsInlineSpecified = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.IsConstexpr = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.IsInitCapture = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = VarDeclBits.getNextBit(); - VD->NonParmVarDeclBits.ImplicitParamKind = - VarDeclBits.getNextBits(/*Width*/ 3); + VD->NonParmVarDeclBits.EscapingByref = VarDeclBits.getNextBit(); HasDeducedType = VarDeclBits.getNextBit(); + VD->NonParmVarDeclBits.ImplicitParamKind = + VarDeclBits.getNextBits(/*Width*/ 3); + + VD->NonParmVarDeclBits.ObjCForDecl = VarDeclBits.getNextBit(); } // If this variable has a deduced type, defer reading that type until we are @@ -1630,7 +1633,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->setType(Reader.GetType(DeferredTypeID)); DeferredTypeID = 0; - auto VarLinkage = Linkage(VarDeclBits.getNextBits(/*Width=*/3)); VD->setCachedLinkage(VarLinkage); // Reconstruct the one piece of the IdentifierNamespace that we need. @@ -1638,7 +1640,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->getLexicalDeclContext()->isFunctionOrMethod()) VD->setLocalExternDecl(); - if (VarDeclBits.getNextBit()) { + if (DefGeneratedInModule) { Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile || Reader.getContext().getLangOpts().BuildingPCHWithObjectFile; @@ -1704,10 +1706,10 @@ void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { VisitVarDecl(PD); + unsigned scopeIndex = Record.readInt(); BitsUnpacker ParmVarDeclBits(Record.readInt()); unsigned isObjCMethodParam = ParmVarDeclBits.getNextBit(); unsigned scopeDepth = ParmVarDeclBits.getNextBits(/*Width=*/7); - unsigned scopeIndex = ParmVarDeclBits.getNextBits(/*Width=*/8); unsigned declQualifier = ParmVarDeclBits.getNextBits(/*Width=*/7); if (isObjCMethodParam) { assert(scopeDepth == 0); @@ -2660,7 +2662,7 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); - if (Record.readBool()) { + if (D->hasTypeConstraint()) { ConceptReference *CR = nullptr; if (Record.readBool()) CR = Record.readConceptReference(); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index b3a6f619372b4a77e1e134075bf8f9586d8c289f..21aed570ba26ce52a9b64f13c9444a028cbfab9f 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -73,6 +73,8 @@ namespace clang { ASTRecordReader &Record; llvm::BitstreamCursor &DeclsCursor; + std::optional CurrentUnpackingBits; + SourceLocation readSourceLocation() { return Record.readSourceLocation(); } @@ -110,6 +112,9 @@ namespace clang { /// itself. static const unsigned NumExprFields = NumStmtFields + 2; + /// The number of bits required for the packing bits for the Expr class. + static const unsigned NumExprBits = 10; + /// Read and initialize a ExplicitTemplateArgumentList structure. void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, TemplateArgumentLoc *ArgsLocArray, @@ -214,9 +219,11 @@ void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) { void ASTStmtReader::VisitIfStmt(IfStmt *S) { VisitStmt(S); - bool HasElse = Record.readInt(); - bool HasVar = Record.readInt(); - bool HasInit = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); + + bool HasElse = CurrentUnpackingBits->getNextBit(); + bool HasVar = CurrentUnpackingBits->getNextBit(); + bool HasInit = CurrentUnpackingBits->getNextBit(); S->setStatementKind(static_cast(Record.readInt())); S->setCond(Record.readSubExpr()); @@ -523,14 +530,15 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { void ASTStmtReader::VisitExpr(Expr *E) { VisitStmt(E); + CurrentUnpackingBits.emplace(Record.readInt()); + E->setDependence(static_cast( + CurrentUnpackingBits->getNextBits(/*Width=*/5))); + E->setValueKind(static_cast( + CurrentUnpackingBits->getNextBits(/*Width=*/2))); + E->setObjectKind(static_cast( + CurrentUnpackingBits->getNextBits(/*Width=*/3))); + E->setType(Record.readType()); - BitsUnpacker ExprBits(Record.readInt()); - E->setDependence( - static_cast(ExprBits.getNextBits(/*Width=*/5))); - E->setValueKind( - static_cast(ExprBits.getNextBits(/*Width=*/2))); - E->setObjectKind( - static_cast(ExprBits.getNextBits(/*Width=*/3))); assert(Record.getIdx() == NumExprFields && "Incorrect expression field count"); } @@ -591,13 +599,17 @@ void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); - E->DeclRefExprBits.HasQualifier = Record.readInt(); - E->DeclRefExprBits.HasFoundDecl = Record.readInt(); - E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record.readInt(); - E->DeclRefExprBits.HadMultipleCandidates = Record.readInt(); - E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt(); - E->DeclRefExprBits.NonOdrUseReason = Record.readInt(); - E->DeclRefExprBits.IsImmediateEscalating = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); + E->DeclRefExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = + CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.NonOdrUseReason = + CurrentUnpackingBits->getNextBits(/*Width=*/2); + E->DeclRefExprBits.IsImmediateEscalating = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HasFoundDecl = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HasQualifier = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HasTemplateKWAndArgsInfo = + CurrentUnpackingBits->getNextBit(); E->DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; unsigned NumTemplateArgs = 0; if (E->hasTemplateKWAndArgsInfo()) @@ -706,12 +718,13 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) { void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); - bool hasFP_Features = Record.readInt(); + bool hasFP_Features = CurrentUnpackingBits->getNextBit(); assert(hasFP_Features == E->hasStoredFPFeatures()); E->setSubExpr(Record.readSubExpr()); - E->setOpcode((UnaryOperator::Opcode)Record.readInt()); + E->setOpcode( + (UnaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/5)); E->setOperatorLoc(readSourceLocation()); - E->setCanOverflow(Record.readInt()); + E->setCanOverflow(CurrentUnpackingBits->getNextBit()); if (hasFP_Features) E->setStoredFPFeatures( FPOptionsOverride::getFromOpaqueInt(Record.readInt())); @@ -1000,12 +1013,11 @@ void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) { void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); - BitsUnpacker CallExprBits = Record.readInt(); - - unsigned NumArgs = CallExprBits.getNextBits(/*Width=*/16); - bool HasFPFeatures = CallExprBits.getNextBit(); + unsigned NumArgs = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); E->setADLCallKind( - static_cast(CallExprBits.getNextBit())); + static_cast(CurrentUnpackingBits->getNextBit())); + bool HasFPFeatures = CurrentUnpackingBits->getNextBit(); assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!"); E->setRParenLoc(readSourceLocation()); E->setCallee(Record.readSubExpr()); @@ -1024,27 +1036,29 @@ void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { void ASTStmtReader::VisitMemberExpr(MemberExpr *E) { VisitExpr(E); - bool HasQualifier = Record.readInt(); - bool HasFoundDecl = Record.readInt(); - bool HasTemplateInfo = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); + bool HasQualifier = CurrentUnpackingBits->getNextBit(); + bool HasFoundDecl = CurrentUnpackingBits->getNextBit(); + bool HasTemplateInfo = CurrentUnpackingBits->getNextBit(); unsigned NumTemplateArgs = Record.readInt(); E->Base = Record.readSubExpr(); E->MemberDecl = Record.readDeclAs(); E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName()); E->MemberLoc = Record.readSourceLocation(); - E->MemberExprBits.IsArrow = Record.readInt(); + E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit(); E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl; E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo; - E->MemberExprBits.HadMultipleCandidates = Record.readInt(); - E->MemberExprBits.NonOdrUseReason = Record.readInt(); + E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit(); + E->MemberExprBits.NonOdrUseReason = + CurrentUnpackingBits->getNextBits(/*Width=*/2); E->MemberExprBits.OperatorLoc = Record.readSourceLocation(); if (HasQualifier || HasFoundDecl) { DeclAccessPair FoundDecl; if (HasFoundDecl) { auto *FoundD = Record.readDeclAs(); - auto AS = (AccessSpecifier)Record.readInt(); + auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2); FoundDecl = DeclAccessPair::make(FoundD, AS); } else { FoundDecl = DeclAccessPair::make(E->MemberDecl, @@ -1091,10 +1105,14 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); unsigned NumBaseSpecs = Record.readInt(); assert(NumBaseSpecs == E->path_size()); - unsigned HasFPFeatures = Record.readInt(); + + CurrentUnpackingBits.emplace(Record.readInt()); + E->setCastKind((CastKind)CurrentUnpackingBits->getNextBits(/*Width=*/7)); + unsigned HasFPFeatures = CurrentUnpackingBits->getNextBit(); assert(E->hasStoredFPFeatures() == HasFPFeatures); + E->setSubExpr(Record.readSubExpr()); - E->setCastKind((CastKind)Record.readInt()); + CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier; @@ -1107,10 +1125,12 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) { } void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) { - bool hasFP_Features; VisitExpr(E); - E->setHasStoredFPFeatures(hasFP_Features = Record.readInt()); - E->setOpcode((BinaryOperator::Opcode)Record.readInt()); + CurrentUnpackingBits.emplace(Record.readInt()); + E->setOpcode( + (BinaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/6)); + bool hasFP_Features = CurrentUnpackingBits->getNextBit(); + E->setHasStoredFPFeatures(hasFP_Features); E->setLHS(Record.readSubExpr()); E->setRHS(Record.readSubExpr()); E->setOperatorLoc(readSourceLocation()); @@ -1148,7 +1168,7 @@ ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) { void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - E->setIsPartOfExplicitCast(Record.readInt()); + E->setIsPartOfExplicitCast(CurrentUnpackingBits->getNextBit()); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { @@ -1764,8 +1784,8 @@ void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { SourceRange R = readSourceRange(); E->Loc = R.getBegin(); E->RParenLoc = R.getEnd(); - R = readSourceRange(); - E->AngleBrackets = R; + if (CurrentUnpackingBits->getNextBit()) + E->AngleBrackets = readSourceRange(); } void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { @@ -1961,9 +1981,10 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr( CXXDependentScopeMemberExpr *E) { VisitExpr(E); - bool HasTemplateKWAndArgsInfo = Record.readInt(); unsigned NumTemplateArgs = Record.readInt(); - bool HasFirstQualifierFoundInScope = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); + bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit(); + bool HasFirstQualifierFoundInScope = CurrentUnpackingBits->getNextBit(); assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) && "Wrong HasTemplateKWAndArgsInfo!"); @@ -1979,11 +2000,18 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr( assert((NumTemplateArgs == E->getNumTemplateArgs()) && "Wrong NumTemplateArgs!"); - E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt(); - E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation(); + E->CXXDependentScopeMemberExprBits.IsArrow = + CurrentUnpackingBits->getNextBit(); + E->BaseType = Record.readType(); E->QualifierLoc = Record.readNestedNameSpecifierLoc(); - E->Base = Record.readSubExpr(); + // not ImplicitAccess + if (CurrentUnpackingBits->getNextBit()) + E->Base = Record.readSubExpr(); + else + E->Base = nullptr; + + E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation(); if (HasFirstQualifierFoundInScope) *E->getTrailingObjects() = readDeclAs(); @@ -1995,11 +2023,11 @@ void ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); - if (Record.readInt()) // HasTemplateKWAndArgsInfo + if (CurrentUnpackingBits->getNextBit()) // HasTemplateKWAndArgsInfo ReadTemplateKWAndArgsInfo( *E->getTrailingObjects(), E->getTrailingObjects(), - /*NumTemplateArgs=*/Record.readInt()); + /*NumTemplateArgs=*/CurrentUnpackingBits->getNextBits(/*Width=*/16)); E->QualifierLoc = Record.readNestedNameSpecifierLoc(); E->NameInfo = Record.readDeclarationNameInfo(); @@ -2022,15 +2050,15 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - BitsUnpacker OverloadExprBits = Record.readInt(); - unsigned NumResults = OverloadExprBits.getNextBits(/*Width=*/14); - bool HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit(); + unsigned NumResults = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); + bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit(); assert((E->getNumDecls() == NumResults) && "Wrong NumResults!"); assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) && "Wrong HasTemplateKWAndArgsInfo!"); if (HasTemplateKWAndArgsInfo) { - unsigned NumTemplateArgs = OverloadExprBits.getNextBits(/*Width=*/14); + unsigned NumTemplateArgs = Record.readInt(); ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(), E->getTrailingTemplateArgumentLoc(), NumTemplateArgs); @@ -2057,17 +2085,24 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { VisitOverloadExpr(E); - E->UnresolvedMemberExprBits.IsArrow = Record.readInt(); - E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt(); - E->Base = Record.readSubExpr(); - E->BaseType = Record.readType(); + E->UnresolvedMemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit(); + E->UnresolvedMemberExprBits.HasUnresolvedUsing = + CurrentUnpackingBits->getNextBit(); + + if (/*!isImplicitAccess=*/CurrentUnpackingBits->getNextBit()) + E->Base = Record.readSubExpr(); + else + E->Base = nullptr; + E->OperatorLoc = readSourceLocation(); + + E->BaseType = Record.readType(); } void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); - E->UnresolvedLookupExprBits.RequiresADL = Record.readInt(); - E->UnresolvedLookupExprBits.Overloaded = Record.readInt(); + E->UnresolvedLookupExprBits.RequiresADL = CurrentUnpackingBits->getNextBit(); + E->UnresolvedLookupExprBits.Overloaded = CurrentUnpackingBits->getNextBit(); E->NamingClass = readDeclAs(); } @@ -2142,9 +2177,12 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { VisitExpr(E); E->AssociatedDeclAndRef.setPointer(readDeclAs()); - E->AssociatedDeclAndRef.setInt(Record.readInt()); - E->Index = Record.readInt(); - E->PackIndex = Record.readInt(); + E->AssociatedDeclAndRef.setInt(CurrentUnpackingBits->getNextBit()); + E->Index = CurrentUnpackingBits->getNextBits(/*Width=*/12); + if (CurrentUnpackingBits->getNextBit()) + E->PackIndex = Record.readInt(); + else + E->PackIndex = 0; E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation(); E->Replacement = Record.readSubExpr(); } @@ -2836,11 +2874,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) NullStmt(Empty); break; - case STMT_COMPOUND: - S = CompoundStmt::CreateEmpty( - Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields], - /*HasFPFeatures=*/Record[ASTStmtReader::NumStmtFields + 1]); + case STMT_COMPOUND: { + unsigned NumStmts = Record[ASTStmtReader::NumStmtFields]; + bool HasFPFeatures = Record[ASTStmtReader::NumStmtFields + 1]; + S = CompoundStmt::CreateEmpty(Context, NumStmts, HasFPFeatures); break; + } case STMT_CASE: S = CaseStmt::CreateEmpty( @@ -2862,13 +2901,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]); break; - case STMT_IF: - S = IfStmt::CreateEmpty( - Context, - /* HasElse=*/Record[ASTStmtReader::NumStmtFields], - /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1], - /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 2]); + case STMT_IF: { + BitsUnpacker IfStmtBits(Record[ASTStmtReader::NumStmtFields]); + bool HasElse = IfStmtBits.getNextBit(); + bool HasVar = IfStmtBits.getNextBit(); + bool HasInit = IfStmtBits.getNextBit(); + S = IfStmt::CreateEmpty(Context, HasElse, HasVar, HasInit); break; + } case STMT_SWITCH: S = SwitchStmt::CreateEmpty( @@ -2945,17 +2985,19 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]); break; - case EXPR_DECL_REF: - S = DeclRefExpr::CreateEmpty( - Context, - /*HasQualifier=*/Record[ASTStmtReader::NumExprFields], - /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1], - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2], - /*NumTemplateArgs=*/ - Record[ASTStmtReader::NumExprFields + 2] - ? Record[ASTStmtReader::NumExprFields + 7] - : 0); + case EXPR_DECL_REF: { + BitsUnpacker DeclRefExprBits(Record[ASTStmtReader::NumExprFields]); + DeclRefExprBits.advance(5); + bool HasFoundDecl = DeclRefExprBits.getNextBit(); + bool HasQualifier = DeclRefExprBits.getNextBit(); + bool HasTemplateKWAndArgsInfo = DeclRefExprBits.getNextBit(); + unsigned NumTemplateArgs = HasTemplateKWAndArgsInfo + ? Record[ASTStmtReader::NumExprFields + 1] + : 0; + S = DeclRefExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl, + HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } case EXPR_INTEGER_LITERAL: S = IntegerLiteral::Create(Context, Empty); @@ -2995,10 +3037,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /* NumExprs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_UNARY_OPERATOR: - S = UnaryOperator::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); + case EXPR_UNARY_OPERATOR: { + BitsUnpacker UnaryOperatorBits(Record[ASTStmtReader::NumStmtFields]); + UnaryOperatorBits.advance(ASTStmtReader::NumExprBits); + bool HasFPFeatures = UnaryOperatorBits.getNextBit(); + S = UnaryOperator::CreateEmpty(Context, HasFPFeatures); break; + } case EXPR_OFFSETOF: S = OffsetOfExpr::CreateEmpty(Context, @@ -3033,8 +3078,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + auto NumArgs = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CallExprBits.advance(1); auto HasFPFeatures = CallExprBits.getNextBit(); S = CallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); break; @@ -3045,22 +3091,32 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_MEMBER: - S = MemberExpr::CreateEmpty(Context, Record[ASTStmtReader::NumExprFields], - Record[ASTStmtReader::NumExprFields + 1], - Record[ASTStmtReader::NumExprFields + 2], - Record[ASTStmtReader::NumExprFields + 3]); + case EXPR_MEMBER: { + BitsUnpacker ExprMemberBits(Record[ASTStmtReader::NumExprFields]); + bool HasQualifier = ExprMemberBits.getNextBit(); + bool HasFoundDecl = ExprMemberBits.getNextBit(); + bool HasTemplateInfo = ExprMemberBits.getNextBit(); + unsigned NumTemplateArgs = Record[ASTStmtReader::NumExprFields + 1]; + S = MemberExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl, + HasTemplateInfo, NumTemplateArgs); break; + } - case EXPR_BINARY_OPERATOR: - S = BinaryOperator::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); + case EXPR_BINARY_OPERATOR: { + BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumExprFields]); + BinaryOperatorBits.advance(/*Size of opcode*/ 6); + bool HasFPFeatures = BinaryOperatorBits.getNextBit(); + S = BinaryOperator::CreateEmpty(Context, HasFPFeatures); break; + } - case EXPR_COMPOUND_ASSIGN_OPERATOR: - S = CompoundAssignOperator::CreateEmpty( - Context, Record[ASTStmtReader::NumExprFields]); + case EXPR_COMPOUND_ASSIGN_OPERATOR: { + BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumExprFields]); + BinaryOperatorBits.advance(/*Size of opcode*/ 6); + bool HasFPFeatures = BinaryOperatorBits.getNextBit(); + S = CompoundAssignOperator::CreateEmpty(Context, HasFPFeatures); break; + } case EXPR_CONDITIONAL_OPERATOR: S = new (Context) ConditionalOperator(Empty); @@ -3070,19 +3126,23 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) BinaryConditionalOperator(Empty); break; - case EXPR_IMPLICIT_CAST: - S = ImplicitCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_IMPLICIT_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CastExprBits.advance(7); + bool HasFPFeatures = CastExprBits.getNextBit(); + S = ImplicitCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } - case EXPR_CSTYLE_CAST: - S = CStyleCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_CSTYLE_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CastExprBits.advance(7); + bool HasFPFeatures = CastExprBits.getNextBit(); + S = CStyleCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } case EXPR_COMPOUND_LITERAL: S = new (Context) CompoundLiteralExpr(Empty); @@ -3777,8 +3837,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { } case EXPR_CXX_OPERATOR_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + auto NumArgs = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CallExprBits.advance(1); auto HasFPFeatures = CallExprBits.getNextBit(); S = CXXOperatorCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); @@ -3786,8 +3847,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { } case EXPR_CXX_MEMBER_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + auto NumArgs = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CallExprBits.advance(1); auto HasFPFeatures = CallExprBits.getNextBit(); S = CXXMemberCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); @@ -3814,22 +3876,26 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /* NumArgs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_CXX_STATIC_CAST: - S = CXXStaticCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_CXX_STATIC_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CastExprBits.advance(7); + bool HasFPFeatures = CastExprBits.getNextBit(); + S = CXXStaticCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } - case EXPR_CXX_DYNAMIC_CAST: - S = CXXDynamicCastExpr::CreateEmpty(Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields]); + case EXPR_CXX_DYNAMIC_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + S = CXXDynamicCastExpr::CreateEmpty(Context, PathSize); break; + } - case EXPR_CXX_REINTERPRET_CAST: - S = CXXReinterpretCastExpr::CreateEmpty(Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields]); + case EXPR_CXX_REINTERPRET_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + S = CXXReinterpretCastExpr::CreateEmpty(Context, PathSize); break; + } case EXPR_CXX_CONST_CAST: S = CXXConstCastExpr::CreateEmpty(Context); @@ -3839,21 +3905,28 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = CXXAddrspaceCastExpr::CreateEmpty(Context); break; - case EXPR_CXX_FUNCTIONAL_CAST: - S = CXXFunctionalCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_CXX_FUNCTIONAL_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CastExprBits.advance(7); + bool HasFPFeatures = CastExprBits.getNextBit(); + S = CXXFunctionalCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } - case EXPR_BUILTIN_BIT_CAST: - assert(Record[ASTStmtReader::NumExprFields] == 0 && "Wrong PathSize!"); + case EXPR_BUILTIN_BIT_CAST: { +#ifndef NDEBUG + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + assert(PathSize == 0 && "Wrong PathSize!"); +#endif S = new (Context) BuiltinBitCastExpr(Empty); break; + } case EXPR_USER_DEFINED_LITERAL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + auto NumArgs = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CallExprBits.advance(1); auto HasFPFeatures = CallExprBits.getNextBit(); S = UserDefinedLiteral::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); @@ -3944,47 +4017,62 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Record[ASTStmtReader::NumExprFields]); break; - case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: + case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: { + unsigned NumTemplateArgs = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker DependentScopeMemberBits( + Record[ASTStmtReader::NumExprFields + 1]); + bool HasTemplateKWAndArgsInfo = DependentScopeMemberBits.getNextBit(); + + bool HasFirstQualifierFoundInScope = + DependentScopeMemberBits.getNextBit(); S = CXXDependentScopeMemberExpr::CreateEmpty( - Context, - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1], - /*HasFirstQualifierFoundInScope=*/ - Record[ASTStmtReader::NumExprFields + 2]); + Context, HasTemplateKWAndArgsInfo, NumTemplateArgs, + HasFirstQualifierFoundInScope); break; + } - case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: - S = DependentScopeDeclRefExpr::CreateEmpty(Context, - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] - ? Record[ASTStmtReader::NumExprFields + 1] - : 0); + case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: { + BitsUnpacker DependentScopeDeclRefBits( + Record[ASTStmtReader::NumStmtFields]); + DependentScopeDeclRefBits.advance(ASTStmtReader::NumExprBits); + bool HasTemplateKWAndArgsInfo = DependentScopeDeclRefBits.getNextBit(); + unsigned NumTemplateArgs = + HasTemplateKWAndArgsInfo + ? DependentScopeDeclRefBits.getNextBits(/*Width=*/16) + : 0; + S = DependentScopeDeclRefExpr::CreateEmpty( + Context, HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } case EXPR_CXX_UNRESOLVED_CONSTRUCT: S = CXXUnresolvedConstructExpr::CreateEmpty(Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_CXX_UNRESOLVED_MEMBER: + case EXPR_CXX_UNRESOLVED_MEMBER: { + auto NumResults = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker OverloadExprBits(Record[ASTStmtReader::NumExprFields + 1]); + auto HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit(); + auto NumTemplateArgs = HasTemplateKWAndArgsInfo + ? Record[ASTStmtReader::NumExprFields + 2] + : 0; S = UnresolvedMemberExpr::CreateEmpty( - Context, - /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1), - /*HasTemplateKWAndArgsInfo=*/ - (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1), - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 & - ((1 << 14) - 1)); + Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } - case EXPR_CXX_UNRESOLVED_LOOKUP: + case EXPR_CXX_UNRESOLVED_LOOKUP: { + auto NumResults = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker OverloadExprBits(Record[ASTStmtReader::NumExprFields + 1]); + auto HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit(); + auto NumTemplateArgs = HasTemplateKWAndArgsInfo + ? Record[ASTStmtReader::NumExprFields + 2] + : 0; S = UnresolvedLookupExpr::CreateEmpty( - Context, - /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1), - /*HasTemplateKWAndArgsInfo=*/ - (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1), - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 & - ((1 << 14) - 1)); + Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } case EXPR_TYPE_TRAIT: S = TypeTraitExpr::CreateDeserialized(Context, @@ -4044,8 +4132,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CUDA_KERNEL_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + auto NumArgs = Record[ASTStmtReader::NumExprFields]; + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]); + CallExprBits.advance(1); auto HasFPFeatures = CallExprBits.getNextBit(); S = CUDAKernelCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 91eb2af8f8ad6a55ce6b8d1b85b6111e93ce098c..78939bfd533ffa541ec43ee3421414cdb5fb5de8 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6003,12 +6003,17 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { BitsPacker DefinitionBits; -#define FIELD(Name, Width, Merge) DefinitionBits.addBits(Data.Name, Width); +#define FIELD(Name, Width, Merge) \ + if (!DefinitionBits.canWriteNextNBits(Width)) { \ + Record->push_back(DefinitionBits); \ + DefinitionBits.reset(0); \ + } \ + DefinitionBits.addBits(Data.Name, Width); + #include "clang/AST/CXXRecordDeclDefinitionBits.def" #undef FIELD - while (DefinitionBits.hasUnconsumedValues()) - Record->push_back(DefinitionBits.getNextValue()); + Record->push_back(DefinitionBits); // getODRHash will compute the ODRHash if it has not been previously computed. Record->push_back(D->getODRHash()); @@ -6047,7 +6052,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { LambdaBits.addBits(Lambda.CaptureDefault, /*Width=*/2); LambdaBits.addBits(Lambda.NumCaptures, /*Width=*/15); LambdaBits.addBit(Lambda.HasKnownInternalLinkage); - Record->push_back(LambdaBits.getNextValue()); + Record->push_back(LambdaBits); Record->push_back(Lambda.NumExplicitCaptures); Record->push_back(Lambda.ManglingNumber); @@ -6058,10 +6063,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { const LambdaCapture &Capture = Lambda.Captures.front()[I]; AddSourceLocation(Capture.getLocation()); + BitsPacker CaptureBits; CaptureBits.addBit(Capture.isImplicit()); CaptureBits.addBits(Capture.getCaptureKind(), /*Width=*/3); Record->push_back(CaptureBits); + switch (Capture.getCaptureKind()) { case LCK_StarThis: case LCK_This: diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 43169b2befc687ed5731f6d189655ff324996b6d..9e3299f0491848497351da5dd1e069450b204e7b 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -321,15 +321,25 @@ void ASTDeclWriter::Visit(Decl *D) { void ASTDeclWriter::VisitDecl(Decl *D) { BitsPacker DeclBits; + + // The order matters here. It will be better to put the bit with higher + // probability to be 0 in the end of the bits. + // + // Since we're using VBR6 format to store it. + // It will be pretty effient if all the higher bits are 0. + // For example, if we need to pack 8 bits into a value and the stored value + // is 0xf0, the actual stored value will be 0b000111'110000, which takes 12 + // bits actually. However, if we changed the order to be 0x0f, then we can + // store it as 0b001111, which takes 6 bits only now. + DeclBits.addBits((uint64_t)D->getModuleOwnershipKind(), /*BitWidth=*/3); + DeclBits.addBit(D->isReferenced()); + DeclBits.addBit(D->isUsed(false)); + DeclBits.addBits(D->getAccess(), /*BitWidth=*/2); + DeclBits.addBit(D->isImplicit()); DeclBits.addBit(D->getDeclContext() != D->getLexicalDeclContext()); - DeclBits.addBit(D->isInvalidDecl()); DeclBits.addBit(D->hasAttrs()); - DeclBits.addBit(D->isImplicit()); - DeclBits.addBit(D->isUsed(false)); - DeclBits.addBit(D->isReferenced()); DeclBits.addBit(D->isTopLevelDeclInObjCContainer()); - DeclBits.addBits(D->getAccess(), /*BitWidth=*/2); - DeclBits.addBits((uint64_t)D->getModuleOwnershipKind(), /*BitWidth=*/3); + DeclBits.addBit(D->isInvalidDecl()); Record.push_back(DeclBits); Record.AddDeclRef(cast_or_null(D->getDeclContext())); @@ -493,21 +503,13 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { Record.AddDeclRef(nullptr); } - if (D->getDeclContext() == D->getLexicalDeclContext() && - !D->hasAttrs() && - !D->isImplicit() && - !D->isUsed(false) && - !D->hasExtInfo() && + if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && + !D->isInvalidDecl() && !D->isImplicit() && !D->hasExtInfo() && !D->getTypedefNameForAnonDecl() && D->getFirstDecl() == D->getMostRecentDecl() && - !D->isInvalidDecl() && - !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && - D->getAccess() == AS_none && - !D->isModulePrivate() && !CXXRecordDecl::classofKind(D->getKind()) && - !D->getIntegerTypeSourceInfo() && - !D->getMemberSpecializationInfo() && + !D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() && !needsAnonymousDeclarationNumber(D) && D->getDeclName().getNameKind() == DeclarationName::Identifier) AbbrevToUse = Writer.getDeclEnumAbbrev(); @@ -542,18 +544,11 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { if (!isa(D)) Record.push_back(D->getODRHash()); - if (D->getDeclContext() == D->getLexicalDeclContext() && - !D->hasAttrs() && - !D->isImplicit() && - !D->isUsed(false) && - !D->hasExtInfo() && + if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && + !D->isImplicit() && !D->isInvalidDecl() && !D->hasExtInfo() && !D->getTypedefNameForAnonDecl() && D->getFirstDecl() == D->getMostRecentDecl() && - !D->isInvalidDecl() && - !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && - D->getAccess() == AS_none && - !D->isModulePrivate() && !CXXRecordDecl::classofKind(D->getKind()) && !needsAnonymousDeclarationNumber(D) && D->getDeclName().getNameKind() == DeclarationName::Identifier) @@ -674,11 +669,16 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName()); Record.push_back(D->getIdentifierNamespace()); + // The order matters here. It will be better to put the bit with higher + // probability to be 0 in the end of the bits. See the comments in VisitDecl + // for details. BitsPacker FunctionDeclBits; // FIXME: stable encoding + FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3); FunctionDeclBits.addBits((uint32_t)D->getStorageClass(), /*BitWidth=*/3); FunctionDeclBits.addBit(D->isInlineSpecified()); FunctionDeclBits.addBit(D->isInlined()); + FunctionDeclBits.addBit(D->hasSkippedBody()); FunctionDeclBits.addBit(D->isVirtualAsWritten()); FunctionDeclBits.addBit(D->isPure()); FunctionDeclBits.addBit(D->hasInheritedPrototype()); @@ -689,14 +689,12 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { FunctionDeclBits.addBit(D->isDefaulted()); FunctionDeclBits.addBit(D->isExplicitlyDefaulted()); FunctionDeclBits.addBit(D->isIneligibleOrNotSelected()); - FunctionDeclBits.addBit(D->hasImplicitReturnZero()); FunctionDeclBits.addBits((uint64_t)(D->getConstexprKind()), /*BitWidth=*/2); - FunctionDeclBits.addBit(D->usesSEHTry()); - FunctionDeclBits.addBit(D->hasSkippedBody()); + FunctionDeclBits.addBit(D->hasImplicitReturnZero()); FunctionDeclBits.addBit(D->isMultiVersion()); FunctionDeclBits.addBit(D->isLateTemplateParsed()); FunctionDeclBits.addBit(D->FriendConstraintRefersToEnclosingTemplate()); - FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3); + FunctionDeclBits.addBit(D->usesSEHTry()); Record.push_back(FunctionDeclBits); Record.AddSourceLocation(D->getEndLoc()); @@ -1060,7 +1058,28 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VisitRedeclarable(D); VisitDeclaratorDecl(D); + // The order matters here. It will be better to put the bit with higher + // probability to be 0 in the end of the bits. See the comments in VisitDecl + // for details. BitsPacker VarDeclBits; + VarDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), + /*BitWidth=*/3); + + bool ModulesCodegen = false; + if (Writer.WritingModule && D->getStorageDuration() == SD_Static && + !D->getDescribedVarTemplate()) { + // When building a C++20 module interface unit or a partition unit, a + // strong definition in the module interface is provided by the + // compilation of that unit, not by its users. (Inline variables are still + // emitted in module users.) + ModulesCodegen = + (Writer.WritingModule->isInterfaceOrPartition() || + (D->hasAttr() && + Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) && + Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal; + } + VarDeclBits.addBit(ModulesCodegen); + VarDeclBits.addBits(D->getStorageClass(), /*BitWidth=*/3); VarDeclBits.addBits(D->getTSCSpec(), /*BitWidth=*/2); VarDeclBits.addBits(D->getInitStyle(), /*BitWidth=*/2); @@ -1072,41 +1091,26 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VarDeclBits.addBit(D->isExceptionVariable()); VarDeclBits.addBit(D->isNRVOVariable()); VarDeclBits.addBit(D->isCXXForRangeDecl()); - VarDeclBits.addBit(D->isObjCForDecl()); + VarDeclBits.addBit(D->isInline()); VarDeclBits.addBit(D->isInlineSpecified()); VarDeclBits.addBit(D->isConstexpr()); VarDeclBits.addBit(D->isInitCapture()); VarDeclBits.addBit(D->isPreviousDeclInSameBlockScope()); + VarDeclBits.addBit(D->isEscapingByref()); + HasDeducedType = D->getType()->getContainedDeducedType(); + VarDeclBits.addBit(HasDeducedType); + if (const auto *IPD = dyn_cast(D)) VarDeclBits.addBits(llvm::to_underlying(IPD->getParameterKind()), /*Width=*/3); else VarDeclBits.addBits(0, /*Width=*/3); - VarDeclBits.addBit(D->isEscapingByref()); - HasDeducedType = D->getType()->getContainedDeducedType(); - VarDeclBits.addBit(HasDeducedType); - } - - VarDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), /*BitWidth=*/3); - - bool ModulesCodegen = false; - if (Writer.WritingModule && D->getStorageDuration() == SD_Static && - !D->getDescribedVarTemplate()) { - // When building a C++20 module interface unit or a partition unit, a - // strong definition in the module interface is provided by the - // compilation of that unit, not by its users. (Inline variables are still - // emitted in module users.) - ModulesCodegen = - (Writer.WritingModule->isInterfaceOrPartition() || - (D->hasAttr() && - Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) && - Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal; + VarDeclBits.addBit(D->isObjCForDecl()); } - VarDeclBits.addBit(ModulesCodegen); Record.push_back(VarDeclBits); if (ModulesCodegen) @@ -1135,29 +1139,17 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(VarNotTemplate); } - if (D->getDeclContext() == D->getLexicalDeclContext() && - !D->hasAttrs() && - !D->isImplicit() && - !D->isUsed(false) && - !D->isInvalidDecl() && - !D->isReferenced() && + if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() && - D->getAccess() == AS_none && - !D->isModulePrivate() && !needsAnonymousDeclarationNumber(D) && D->getDeclName().getNameKind() == DeclarationName::Identifier && - !D->hasExtInfo() && - D->getFirstDecl() == D->getMostRecentDecl() && - D->getKind() == Decl::Var && - !D->isInline() && - !D->isConstexpr() && - !D->isInitCapture() && - !D->isPreviousDeclInSameBlockScope() && - !D->isEscapingByref() && - !HasDeducedType && - D->getStorageDuration() != SD_Static && - !D->getDescribedVarTemplate() && - !D->getMemberSpecializationInfo()) + !D->hasExtInfo() && D->getFirstDecl() == D->getMostRecentDecl() && + D->getKind() == Decl::Var && !D->isInline() && !D->isConstexpr() && + !D->isInitCapture() && !D->isPreviousDeclInSameBlockScope() && + !D->isEscapingByref() && !HasDeducedType && + D->getStorageDuration() != SD_Static && !D->getDescribedVarTemplate() && + !D->getMemberSpecializationInfo() && !D->isObjCForDecl() && + !isa(D) && !D->isEscapingByref()) AbbrevToUse = Writer.getDeclVarAbbrev(); Code = serialization::DECL_VAR; @@ -1171,10 +1163,14 @@ void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) { void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { VisitVarDecl(D); + // See the implementation of `ParmVarDecl::getParameterIndex()`, which may + // exceed the size of the normal bitfield. So it may be better to not pack + // these bits. + Record.push_back(D->getFunctionScopeIndex()); + BitsPacker ParmVarDeclBits; ParmVarDeclBits.addBit(D->isObjCMethodParameter()); ParmVarDeclBits.addBits(D->getFunctionScopeDepth(), /*BitsWidth=*/7); - ParmVarDeclBits.addBits(D->getFunctionScopeIndex(), /*BitsWidth=*/8); // FIXME: stable encoding ParmVarDeclBits.addBits(D->getObjCDeclQualifier(), /*BitsWidth=*/7); ParmVarDeclBits.addBit(D->isKNRPromoted()); @@ -1193,14 +1189,10 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // we dynamically check for the properties that we optimize for, but don't // know are true of all PARM_VAR_DECLs. if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && - !D->hasExtInfo() && !D->isImplicit() && !D->isUsed(false) && - !D->isInvalidDecl() && !D->isReferenced() && D->getAccess() == AS_none && - !D->isModulePrivate() && D->getStorageClass() == 0 && + !D->hasExtInfo() && D->getStorageClass() == 0 && !D->isInvalidDecl() && + !D->isTopLevelDeclInObjCContainer() && D->getInitStyle() == VarDecl::CInit && // Can params have anything else? - D->getFunctionScopeDepth() == 0 && D->getObjCDeclQualifier() == 0 && - !D->isKNRPromoted() && !D->isExplicitObjectParameter() && - !D->hasInheritedDefaultArg() && D->getInit() == nullptr && - !D->hasUninstantiatedDefaultArg()) // No default expr. + D->getInit() == nullptr) // No default expr. AbbrevToUse = Writer.getDeclParmVarAbbrev(); // Check things we know are true of *every* PARM_VAR_DECL, which is more than @@ -1403,6 +1395,13 @@ void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) { Record.push_back(D->getIdentifierNamespace()); Record.AddDeclRef(D->UsingOrNextShadow); Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D)); + + if (D->getDeclContext() == D->getLexicalDeclContext() && + D->getFirstDecl() == D->getMostRecentDecl() && !D->hasAttrs() && + !needsAnonymousDeclarationNumber(D) && + D->getDeclName().getNameKind() == DeclarationName::Identifier) + AbbrevToUse = Writer.getDeclUsingShadowAbbrev(); + Code = serialization::DECL_USING_SHADOW; } @@ -1507,10 +1506,32 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) { D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() && D->getDeclName().getNameKind() == DeclarationName::Identifier && - !D->hasExtInfo() && !D->hasInheritedPrototype() && - D->hasWrittenPrototype() && - D->getTemplatedKind() == FunctionDecl::TK_NonTemplate) - AbbrevToUse = Writer.getDeclCXXMethodAbbrev(); + !D->hasExtInfo() && !D->isExplicitlyDefaulted()) { + if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate || + D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate || + D->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization || + D->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) + AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind()); + else if (D->getTemplatedKind() == + FunctionDecl::TK_FunctionTemplateSpecialization) { + FunctionTemplateSpecializationInfo *FTSInfo = + D->getTemplateSpecializationInfo(); + + if (FTSInfo->TemplateArguments->size() == 1) { + const TemplateArgument &TA = FTSInfo->TemplateArguments->get(0); + if (TA.getKind() == TemplateArgument::Type && + !FTSInfo->TemplateArgumentsAsWritten && + !FTSInfo->getMemberSpecializationInfo()) + AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind()); + } + } else if (D->getTemplatedKind() == + FunctionDecl::TK_DependentFunctionTemplateSpecialization) { + DependentFunctionTemplateSpecializationInfo *DFTSInfo = + D->getDependentSpecializationInfo(); + if (!DFTSInfo->TemplateArgumentsAsWritten) + AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind()); + } + } Code = serialization::DECL_CXX_METHOD; } @@ -1782,7 +1803,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { Record.push_back(D->wasDeclaredWithTypename()); const TypeConstraint *TC = D->getTypeConstraint(); - Record.push_back(TC != nullptr); + assert((bool)TC == D->hasTypeConstraint()); if (TC) { auto *CR = TC->getConceptReference(); Record.push_back(CR != nullptr); @@ -1800,6 +1821,13 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { if (OwnsDefaultArg) Record.AddTypeSourceInfo(D->getDefaultArgumentInfo()); + if (!TC && !OwnsDefaultArg && + D->getDeclContext() == D->getLexicalDeclContext() && + !D->isInvalidDecl() && !D->hasAttrs() && + !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() && + D->getDeclName().getNameKind() == DeclarationName::Identifier) + AbbrevToUse = Writer.getDeclTemplateTypeParmAbbrev(); + Code = serialization::DECL_TEMPLATE_TYPE_PARM; } @@ -2031,6 +2059,106 @@ void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { // ASTWriter Implementation //===----------------------------------------------------------------------===// +namespace { +template +std::shared_ptr +getFunctionDeclAbbrev(serialization::DeclCode Code) { + using namespace llvm; + + auto Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(Code)); + // RedeclarableDecl + Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl + Abv->Add(BitCodeAbbrevOp(Kind)); + if constexpr (Kind == FunctionDecl::TK_NonTemplate) { + + } else if constexpr (Kind == FunctionDecl::TK_FunctionTemplate) { + // DescribedFunctionTemplate + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + } else if constexpr (Kind == FunctionDecl::TK_DependentNonTemplate) { + // Instantiated From Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + } else if constexpr (Kind == FunctionDecl::TK_MemberSpecialization) { + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedFrom + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 3)); // TemplateSpecializationKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Specialized Location + } else if constexpr (Kind == + FunctionDecl::TK_FunctionTemplateSpecialization) { + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 3)); // TemplateSpecializationKind + Abv->Add(BitCodeAbbrevOp(1)); // Template Argument Size + Abv->Add(BitCodeAbbrevOp(TemplateArgument::Type)); // Template Argument Kind + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template Argument Type + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is Defaulted + Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation + Abv->Add(BitCodeAbbrevOp(0)); + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Canonical Decl of template + } else if constexpr (Kind == FunctionDecl:: + TK_DependentFunctionTemplateSpecialization) { + // Candidates of specialization + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten + } else { + llvm_unreachable("Unknown templated kind?"); + } + // Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 8)); // Packed DeclBits: ModuleOwnershipKind, + // isUsed, isReferenced, AccessSpecifier, + // isImplicit + // + // The following bits should be 0: + // HasStandaloneLexicalDC, HasAttrs, + // TopLevelDeclInObjCContainer, + // isInvalidDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID + // NamedDecl + Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber + // ValueDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // DeclaratorDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart + Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType + // FunctionDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS + Abv->Add(BitCodeAbbrevOp( + BitCodeAbbrevOp::Fixed, + 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified, + // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto, + // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted, + // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr, + // UsesSEHTry, SkippedBody, MultiVersion, LateParsed, + // FriendConstraintRefersToEnclosingTemplate, Linkage + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash + // This Array slurps the rest of the record. Fortunately we want to encode + // (nearly) all the remaining (variable number of) fields in the same way. + // + // This is: + // NumParams and Params[] from FunctionDecl, and + // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl. + // + // Add an AbbrevOp for 'size then elements' and use it here. + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + return Abv; +} + +template +std::shared_ptr getCXXMethodAbbrev() { + return getFunctionDeclAbbrev(serialization::DECL_CXX_METHOD); +} +} // namespace + void ASTWriter::WriteDeclAbbrevs() { using namespace llvm; @@ -2041,10 +2169,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD)); // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - 12)); // Packed DeclBits: HasStandaloneLexicalDC, - // isInvalidDecl, HasAttrs, isImplicit, isUsed, - // isReferenced, TopLevelDeclInObjCContainer, - // AccessSpecifier, ModuleOwnershipKind + 7)); // Packed DeclBits: ModuleOwnershipKind, + // isUsed, isReferenced, AccessSpecifier, + // + // The following bits should be 0: + // isImplicit, HasStandaloneLexicalDC, HasAttrs, + // TopLevelDeclInObjCContainer, + // isInvalidDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl @@ -2104,10 +2235,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - 12)); // Packed DeclBits: HasStandaloneLexicalDC, - // isInvalidDecl, HasAttrs, isImplicit, isUsed, - // isReferenced, TopLevelDeclInObjCContainer, - // AccessSpecifier, ModuleOwnershipKind + 7)); // Packed DeclBits: ModuleOwnershipKind, + // isUsed, isReferenced, AccessSpecifier, + // + // The following bits should be 0: + // isImplicit, HasStandaloneLexicalDC, HasAttrs, + // TopLevelDeclInObjCContainer, + // isInvalidDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl @@ -2145,10 +2279,13 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - 12)); // Packed DeclBits: HasStandaloneLexicalDC, - // isInvalidDecl, HasAttrs, isImplicit, isUsed, - // isReferenced, TopLevelDeclInObjCContainer, - // AccessSpecifier, ModuleOwnershipKind + 7)); // Packed DeclBits: ModuleOwnershipKind, + // isUsed, isReferenced, AccessSpecifier, + // + // The following bits should be 0: + // isImplicit, HasStandaloneLexicalDC, HasAttrs, + // TopLevelDeclInObjCContainer, + // isInvalidDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl @@ -2193,10 +2330,11 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - 12)); // Packed DeclBits: HasStandaloneLexicalDC, - // isInvalidDecl, HasAttrs, isImplicit, isUsed, - // isReferenced, TopLevelDeclInObjCContainer, - // AccessSpecifier, ModuleOwnershipKind + 8)); // Packed DeclBits: ModuleOwnershipKind, isUsed, + // isReferenced, AccessSpecifier, + // HasStandaloneLexicalDC, HasAttrs, isImplicit, + // TopLevelDeclInObjCContainer, + // isInvalidDecl, Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl @@ -2216,10 +2354,11 @@ void ASTWriter::WriteDeclAbbrevs() { // isARCPseudoStrong, Linkage, ModulesCodegen Abv->Add(BitCodeAbbrevOp(0)); // VarKind (local enum) // ParmVarDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex Abv->Add(BitCodeAbbrevOp( BitCodeAbbrevOp::Fixed, - 27)); // Packed Parm Var Decl bits: IsObjCMethodParameter, ScopeDepth, - // ScopeIndex, ObjCDeclQualifier, KNRPromoted, + 19)); // Packed Parm Var Decl bits: IsObjCMethodParameter, ScopeDepth, + // ObjCDeclQualifier, KNRPromoted, // HasInheritedDefaultArg, HasUninstantiatedDefaultArg // Type Source Info Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); @@ -2233,10 +2372,11 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - 12)); // Packed DeclBits: HasStandaloneLexicalDC, - // isInvalidDecl, HasAttrs, isImplicit, isUsed, - // isReferenced, TopLevelDeclInObjCContainer, - // AccessSpecifier, ModuleOwnershipKind + 7)); // Packed DeclBits: ModuleOwnershipKind, + // isReferenced, isUsed, AccessSpecifier. Other + // higher bits should be 0: isImplicit, + // HasStandaloneLexicalDC, HasAttrs, + // TopLevelDeclInObjCContainer, isInvalidDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl @@ -2277,12 +2417,13 @@ void ASTWriter::WriteDeclAbbrevs() { // VarDecl Abv->Add(BitCodeAbbrevOp( BitCodeAbbrevOp::Fixed, - 27)); // Packed Var Decl bits: SClass, TSCSpec, InitStyle, + 21)); // Packed Var Decl bits: Linkage, ModulesCodegen, + // SClass, TSCSpec, InitStyle, // isARCPseudoStrong, IsThisDeclarationADemotedDefinition, // isExceptionVariable, isNRVOVariable, isCXXForRangeDecl, - // isObjCForDecl, isInline, isInlineSpecified, isConstexpr, - // isInitCapture, isPrevDeclInSameScope, ImplicitParamKind, - // EscapingByref, HasDeducedType, Linkage, ModulesCodegen + // isInline, isInlineSpecified, isConstexpr, + // isInitCapture, isPrevDeclInSameScope, + // EscapingByref, HasDeducedType, ImplicitParamKind, isObjCForDecl Abv->Add(BitCodeAbbrevOp(0)); // VarKind (local enum) // Type Source Info Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); @@ -2290,71 +2431,84 @@ void ASTWriter::WriteDeclAbbrevs() { DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv)); // Abbreviation for DECL_CXX_METHOD + DeclCXXMethodAbbrev = + Stream.EmitAbbrev(getCXXMethodAbbrev()); + DeclTemplateCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclDependentNonTemplateCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclMemberSpecializedCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclTemplateSpecializedCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclDependentSpecializationCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev< + FunctionDecl::TK_DependentFunctionTemplateSpecialization>()); + + // Abbreviation for DECL_TEMPLATE_TYPE_PARM Abv = std::make_shared(); - Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD)); - // RedeclarableDecl - Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl - // FIXME: Implement abbreviation for other template kinds. - Abv->Add(BitCodeAbbrevOp(FunctionDecl::TK_NonTemplate)); // TemplateKind + Abv->Add(BitCodeAbbrevOp(serialization::DECL_TEMPLATE_TYPE_PARM)); + Abv->Add(BitCodeAbbrevOp(0)); // hasTypeConstraint + // Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 7)); // Packed DeclBits: ModuleOwnershipKind, + // isReferenced, isUsed, AccessSpecifier. Other + // higher bits should be 0: isImplicit, + // HasStandaloneLexicalDC, HasAttrs, + // TopLevelDeclInObjCContainer, isInvalidDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID + // NamedDecl + Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); + // TypeDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref + // TemplateTypeParmDecl + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename + Abv->Add(BitCodeAbbrevOp(0)); // OwnsDefaultArg + DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for DECL_USING_SHADOW + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::DECL_USING_SHADOW)); + // Redeclarable + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 12)); // Packed DeclBits: HasStandaloneLexicalDC, // isInvalidDecl, HasAttrs, isImplicit, isUsed, // isReferenced, TopLevelDeclInObjCContainer, // AccessSpecifier, ModuleOwnershipKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl - Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier - Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber - // ValueDecl - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - // DeclaratorDecl - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart - Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType - // FunctionDecl + Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); + // UsingShadowDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TargetDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS - Abv->Add(BitCodeAbbrevOp( - BitCodeAbbrevOp::Fixed, - 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified, - // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto, - // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted, - // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr, - // UsesSEHTry, SkippedBody, MultiVersion, LateParsed, - // FriendConstraintRefersToEnclosingTemplate, Linkage - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Default - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash - // This Array slurps the rest of the record. Fortunately we want to encode - // (nearly) all the remaining (variable number of) fields in the same way. - // - // This is: - // NumParams and Params[] from FunctionDecl, and - // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl. - // - // Add an AbbrevOp for 'size then elements' and use it here. - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // UsingOrNextShadow + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, + 6)); // InstantiatedFromUsingShadowDecl + DeclUsingShadowAbbrev = Stream.EmitAbbrev(std::move(Abv)); // Abbreviation for EXPR_DECL_REF Abv = std::make_shared(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF)); - //Stmt - // Expr + // Stmt + // Expr + // PackingBits: DependenceKind, ValueKind. ObjectKind should be 0. + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - // DependenceKind, ValueKind, ObjectKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); - //DeclRefExpr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates - Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture - Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason - Abv->Add(BitCodeAbbrevOp(0)); // IsImmediateEscalating + // DeclRefExpr + // Packing Bits: , HadMultipleCandidates, RefersToEnclosingVariableOrCapture, + // IsImmediateEscalating, NonOdrUseReason. + // GetDeclFound, HasQualifier and ExplicitTemplateArgs should be 0. + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); @@ -2364,10 +2518,10 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL)); //Stmt // Expr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DependenceKind, ValueKind, ObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); - //Integer Literal + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // Integer Literal Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location Abv->Add(BitCodeAbbrevOp(32)); // Bit Width Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value @@ -2378,10 +2532,10 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL)); //Stmt // Expr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DependenceKind, ValueKind, ObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); - //Character Literal + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // Character Literal Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind @@ -2392,17 +2546,108 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST)); // Stmt // Expr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - // DependenceKind, ValueKind, ObjectKind + // Packing Bits: DependenceKind, ValueKind, ObjectKind, Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // CastExpr Abv->Add(BitCodeAbbrevOp(0)); // PathSize - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasFPFeatures - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast + // Packing Bits: CastKind, StoredFPFeatures, isPartOfExplicitCast + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 9)); // ImplicitCastExpr ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv)); + // Abbreviation for EXPR_BINARY_OPERATOR + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_BINARY_OPERATOR)); + // Stmt + // Expr + // Packing Bits: DependenceKind. ValueKind and ObjectKind should + // be 0 in this case. + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // BinaryOperator + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpCode and HasFPFeatures + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + BinaryOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_COMPOUND_ASSIGN_OPERATOR + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_COMPOUND_ASSIGN_OPERATOR)); + // Stmt + // Expr + // Packing Bits: DependenceKind. ValueKind and ObjectKind should + // be 0 in this case. + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // BinaryOperator + // Packing Bits: OpCode. The HasFPFeatures bit should be 0 + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpCode and HasFPFeatures + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + // CompoundAssignOperator + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHSType + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Result Type + CompoundAssignOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_CALL + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CALL)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // CallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs + Abv->Add(BitCodeAbbrevOp(0)); // ADLCallKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + CallExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_CXX_OPERATOR_CALL + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_OPERATOR_CALL)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // CallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs + Abv->Add(BitCodeAbbrevOp(0)); // ADLCallKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + // CXXOperatorCallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Operator Kind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + CXXOperatorCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_CXX_MEMBER_CALL + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_MEMBER_CALL)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // CallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs + Abv->Add(BitCodeAbbrevOp(0)); // ADLCallKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + // CXXMemberCallExpr + CXXMemberCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for STMT_COMPOUND + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::STMT_COMPOUND)); + // Stmt + // CompoundStmt + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Num Stmts + Abv->Add(BitCodeAbbrevOp(0)); // hasStoredFPFeatures + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + CompoundStmtAbbrev = Stream.EmitAbbrev(std::move(Abv)); + Abv = std::make_shared(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 8524484ea8a0b98e559bdf0b20fb8d5f2fae4799..7f888e44dde1e0ff645c1c0033eefd8451479870 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -37,15 +37,70 @@ namespace clang { serialization::StmtCode Code; unsigned AbbrevToUse; + /// A helper that can help us to write a packed bit across function + /// calls. For example, we may write seperate bits in seperate functions: + /// + /// void VisitA(A* a) { + /// Record.push_back(a->isSomething()); + /// } + /// + /// void Visitb(B *b) { + /// VisitA(b); + /// Record.push_back(b->isAnother()); + /// } + /// + /// In such cases, it'll be better if we can pack these 2 bits. We achieve + /// this by writing a zero value in `VisitA` and recorded that first and add + /// the new bit to the recorded value. + class PakedBitsWriter { + public: + PakedBitsWriter(ASTRecordWriter &Record) : RecordRef(Record) {} + ~PakedBitsWriter() { assert(!CurrentIndex); } + + void addBit(bool Value) { + assert(CurrentIndex && "Writing Bits without recording first!"); + PackingBits.addBit(Value); + } + void addBits(uint32_t Value, uint32_t BitsWidth) { + assert(CurrentIndex && "Writing Bits without recording first!"); + PackingBits.addBits(Value, BitsWidth); + } + + void writeBits() { + if (!CurrentIndex) + return; + + RecordRef[*CurrentIndex] = (uint32_t)PackingBits; + CurrentIndex = std::nullopt; + PackingBits.reset(0); + } + + void updateBits() { + writeBits(); + + CurrentIndex = RecordRef.size(); + RecordRef.push_back(0); + } + + private: + BitsPacker PackingBits; + ASTRecordWriter &RecordRef; + std::optional CurrentIndex; + }; + + PakedBitsWriter CurrentPackingBits; + public: ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) : Writer(Writer), Record(Writer, Record), - Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {} + Code(serialization::STMT_NULL_PTR), AbbrevToUse(0), + CurrentPackingBits(this->Record) {} ASTStmtWriter(const ASTStmtWriter&) = delete; ASTStmtWriter &operator=(const ASTStmtWriter &) = delete; uint64_t Emit() { + CurrentPackingBits.writeBits(); assert(Code != serialization::STMT_NULL_PTR && "unhandled sub-statement writing AST file"); return Record.EmitStmt(Code, AbbrevToUse); @@ -82,14 +137,20 @@ void ASTStmtWriter::VisitNullStmt(NullStmt *S) { void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) { VisitStmt(S); + Record.push_back(S->size()); Record.push_back(S->hasStoredFPFeatures()); + for (auto *CS : S->body()) Record.AddStmt(CS); if (S->hasStoredFPFeatures()) Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt()); Record.AddSourceLocation(S->getLBracLoc()); Record.AddSourceLocation(S->getRBracLoc()); + + if (!S->hasStoredFPFeatures()) + AbbrevToUse = Writer.getCompoundStmtAbbrev(); + Code = serialization::STMT_COMPOUND; } @@ -143,9 +204,11 @@ void ASTStmtWriter::VisitIfStmt(IfStmt *S) { bool HasVar = S->getConditionVariableDeclStmt() != nullptr; bool HasInit = S->getInit() != nullptr; - Record.push_back(HasElse); - Record.push_back(HasVar); - Record.push_back(HasInit); + CurrentPackingBits.updateBits(); + + CurrentPackingBits.addBit(HasElse); + CurrentPackingBits.addBit(HasVar); + CurrentPackingBits.addBit(HasInit); Record.push_back(static_cast(S->getStatementKind())); Record.AddStmt(S->getCond()); Record.AddStmt(S->getThen()); @@ -548,15 +611,13 @@ void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) { void ASTStmtWriter::VisitExpr(Expr *E) { VisitStmt(E); - Record.AddTypeRef(E->getType()); - BitsPacker ExprBits; + CurrentPackingBits.updateBits(); + CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5); + CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2); + CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3); - ExprBits.addBits(E->getDependence(), /*BitsWidth=*/5); - ExprBits.addBits(E->getValueKind(), /*BitsWidth=*/2); - ExprBits.addBits(E->getObjectKind(), /*BitsWidth=*/3); - - Record.push_back(ExprBits); + Record.AddTypeRef(E->getType()); } void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) { @@ -612,13 +673,15 @@ void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) { void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); - Record.push_back(E->hasQualifier()); - Record.push_back(E->getDecl() != E->getFoundDecl()); - Record.push_back(E->hasTemplateKWAndArgsInfo()); - Record.push_back(E->hadMultipleCandidates()); - Record.push_back(E->refersToEnclosingVariableOrCapture()); - Record.push_back(E->isNonOdrUse()); - Record.push_back(E->isImmediateEscalating()); + CurrentPackingBits.updateBits(); + + CurrentPackingBits.addBit(E->hadMultipleCandidates()); + CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture()); + CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2); + CurrentPackingBits.addBit(E->isImmediateEscalating()); + CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl()); + CurrentPackingBits.addBit(E->hasQualifier()); + CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo()); if (E->hasTemplateKWAndArgsInfo()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); @@ -629,9 +692,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) && (E->getDecl() == E->getFoundDecl()) && - nk == DeclarationName::Identifier && - !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse() && - !E->isImmediateEscalating()) { + nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary) { AbbrevToUse = Writer.getDeclRefExprAbbrev(); } @@ -742,11 +803,13 @@ void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) { bool HasFPFeatures = E->hasStoredFPFeatures(); // Write this first for easy access when deserializing, as they affect the // size of the UnaryOperator. - Record.push_back(HasFPFeatures); + CurrentPackingBits.addBit(HasFPFeatures); Record.AddStmt(E->getSubExpr()); - Record.push_back(E->getOpcode()); // FIXME: stable encoding + CurrentPackingBits.addBits(E->getOpcode(), + /*Width=*/5); // FIXME: stable encoding Record.AddSourceLocation(E->getOperatorLoc()); - Record.push_back(E->canOverflow()); + CurrentPackingBits.addBit(E->canOverflow()); + if (HasFPFeatures) Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt()); Code = serialization::EXPR_UNARY_OPERATOR; @@ -872,12 +935,10 @@ void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) { void ASTStmtWriter::VisitCallExpr(CallExpr *E) { VisitExpr(E); - BitsPacker CallExprBits; - // 16 bits should be sufficient to store the number args; - CallExprBits.addBits(E->getNumArgs(), /*BitsWidth=*/16); - CallExprBits.addBit(E->hasStoredFPFeatures()); - CallExprBits.addBit(static_cast(E->getADLCallKind())); - Record.push_back(CallExprBits); + Record.push_back(E->getNumArgs()); + CurrentPackingBits.updateBits(); + CurrentPackingBits.addBit(static_cast(E->getADLCallKind())); + CurrentPackingBits.addBit(E->hasStoredFPFeatures()); Record.AddSourceLocation(E->getRParenLoc()); Record.AddStmt(E->getCallee()); @@ -887,6 +948,11 @@ void ASTStmtWriter::VisitCallExpr(CallExpr *E) { if (E->hasStoredFPFeatures()) Record.push_back(E->getFPFeatures().getAsOpaqueInt()); + + if (!E->hasStoredFPFeatures() && !static_cast(E->getADLCallKind()) && + E->getStmtClass() == Stmt::CallExprClass) + AbbrevToUse = Writer.getCallExprAbbrev(); + Code = serialization::EXPR_CALL; } @@ -913,9 +979,10 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { // Write these first for easy access when deserializing, as they affect the // size of the MemberExpr. - Record.push_back(HasQualifier); - Record.push_back(HasFoundDecl); - Record.push_back(HasTemplateInfo); + CurrentPackingBits.updateBits(); + CurrentPackingBits.addBit(HasQualifier); + CurrentPackingBits.addBit(HasFoundDecl); + CurrentPackingBits.addBit(HasTemplateInfo); Record.push_back(NumTemplateArgs); Record.AddStmt(E->getBase()); @@ -923,15 +990,15 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { Record.AddDeclarationNameLoc(E->MemberDNLoc, E->getMemberDecl()->getDeclName()); Record.AddSourceLocation(E->getMemberLoc()); - Record.push_back(E->isArrow()); - Record.push_back(E->hadMultipleCandidates()); - Record.push_back(E->isNonOdrUse()); + CurrentPackingBits.addBit(E->isArrow()); + CurrentPackingBits.addBit(E->hadMultipleCandidates()); + CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2); Record.AddSourceLocation(E->getOperatorLoc()); if (HasFoundDecl) { DeclAccessPair FoundDecl = E->getFoundDecl(); Record.AddDeclRef(FoundDecl.getDecl()); - Record.push_back(FoundDecl.getAccess()); + CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2); } if (HasQualifier) @@ -971,10 +1038,13 @@ void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { void ASTStmtWriter::VisitCastExpr(CastExpr *E) { VisitExpr(E); + Record.push_back(E->path_size()); - Record.push_back(E->hasStoredFPFeatures()); + CurrentPackingBits.updateBits(); + // 7 bits should be enough to store the casting kinds. + CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7); + CurrentPackingBits.addBit(E->hasStoredFPFeatures()); Record.AddStmt(E->getSubExpr()); - Record.push_back(E->getCastKind()); // FIXME: stable encoding for (CastExpr::path_iterator PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI) @@ -986,16 +1056,23 @@ void ASTStmtWriter::VisitCastExpr(CastExpr *E) { void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) { VisitExpr(E); - bool HasFPFeatures = E->hasStoredFPFeatures(); + // Write this first for easy access when deserializing, as they affect the // size of the UnaryOperator. - Record.push_back(HasFPFeatures); - Record.push_back(E->getOpcode()); // FIXME: stable encoding + CurrentPackingBits.updateBits(); + CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6); + bool HasFPFeatures = E->hasStoredFPFeatures(); + CurrentPackingBits.addBit(HasFPFeatures); Record.AddStmt(E->getLHS()); Record.AddStmt(E->getRHS()); Record.AddSourceLocation(E->getOperatorLoc()); if (HasFPFeatures) Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt()); + + if (!HasFPFeatures && E->getValueKind() == VK_PRValue && + E->getObjectKind() == OK_Ordinary) + AbbrevToUse = Writer.getBinaryOperatorAbbrev(); + Code = serialization::EXPR_BINARY_OPERATOR; } @@ -1003,6 +1080,11 @@ void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { VisitBinaryOperator(E); Record.AddTypeRef(E->getComputationLHSType()); Record.AddTypeRef(E->getComputationResultType()); + + if (!E->hasStoredFPFeatures() && E->getValueKind() == VK_PRValue && + E->getObjectKind() == OK_Ordinary) + AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev(); + Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR; } @@ -1031,7 +1113,7 @@ ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) { void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - Record.push_back(E->isPartOfExplicitCast()); + CurrentPackingBits.addBit(E->isPartOfExplicitCast()); if (E->path_size() == 0 && !E->hasStoredFPFeatures()) AbbrevToUse = Writer.getExprImplicitCastAbbrev(); @@ -1588,11 +1670,19 @@ void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); Record.push_back(E->getOperator()); Record.AddSourceRange(E->Range); + + if (!E->hasStoredFPFeatures() && !static_cast(E->getADLCallKind())) + AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev(); + Code = serialization::EXPR_CXX_OPERATOR_CALL; } void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { VisitCallExpr(E); + + if (!E->hasStoredFPFeatures() && !static_cast(E->getADLCallKind())) + AbbrevToUse = Writer.getCXXMemberCallExprAbbrev(); + Code = serialization::EXPR_CXX_MEMBER_CALL; } @@ -1673,7 +1763,9 @@ void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { VisitExplicitCastExpr(E); Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc())); - Record.AddSourceRange(E->getAngleBrackets()); + CurrentPackingBits.addBit(E->getAngleBrackets().isValid()); + if (E->getAngleBrackets().isValid()) + Record.AddSourceRange(E->getAngleBrackets()); } void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { @@ -1750,6 +1842,7 @@ void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) { VisitExpr(E); Record.AddSourceLocation(E->getLocation()); Record.push_back(E->isImplicit()); + Code = serialization::EXPR_CXX_THIS; } @@ -1883,10 +1976,10 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr( // Don't emit anything here (or if you do you will have to update // the corresponding deserialization function). - - Record.push_back(E->hasTemplateKWAndArgsInfo()); Record.push_back(E->getNumTemplateArgs()); - Record.push_back(E->hasFirstQualifierFoundInScope()); + CurrentPackingBits.updateBits(); + CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo()); + CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope()); if (E->hasTemplateKWAndArgsInfo()) { const ASTTemplateKWAndArgsInfo &ArgInfo = @@ -1895,14 +1988,15 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr( E->getTrailingObjects()); } - Record.push_back(E->isArrow()); - Record.AddSourceLocation(E->getOperatorLoc()); + CurrentPackingBits.addBit(E->isArrow()); + Record.AddTypeRef(E->getBaseType()); Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); + CurrentPackingBits.addBit(!E->isImplicitAccess()); if (!E->isImplicitAccess()) Record.AddStmt(E->getBase()); - else - Record.AddStmt(nullptr); + + Record.AddSourceLocation(E->getOperatorLoc()); if (E->hasFirstQualifierFoundInScope()) Record.AddDeclRef(E->getFirstQualifierFoundInScope()); @@ -1917,12 +2011,14 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { // Don't emit anything here, HasTemplateKWAndArgsInfo must be // emitted first. + CurrentPackingBits.addBit( + E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo); - Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo); if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) { const ASTTemplateKWAndArgsInfo &ArgInfo = *E->getTrailingObjects(); - Record.push_back(ArgInfo.NumTemplateArgs); + // 16 bits should be enought to store the number of args + CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16); AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingObjects()); } @@ -1949,19 +2045,16 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - BitsPacker OverloadExprBits; - // 14 Bits should enough to store the number of decls. - OverloadExprBits.addBits(E->getNumDecls(), /*BitWidth=*/14); - OverloadExprBits.addBit(E->hasTemplateKWAndArgsInfo()); + Record.push_back(E->getNumDecls()); + + CurrentPackingBits.updateBits(); + CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo()); if (E->hasTemplateKWAndArgsInfo()) { const ASTTemplateKWAndArgsInfo &ArgInfo = *E->getTrailingASTTemplateKWAndArgsInfo(); - // 14 Bits should enough to store the number of template args. - OverloadExprBits.addBits(ArgInfo.NumTemplateArgs, /*BitWidth=*/14); - Record.push_back(OverloadExprBits); + Record.push_back(ArgInfo.NumTemplateArgs); AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc()); - } else - Record.push_back(OverloadExprBits); + } for (OverloadExpr::decls_iterator OvI = E->decls_begin(), OvE = E->decls_end(); @@ -1976,18 +2069,22 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { VisitOverloadExpr(E); - Record.push_back(E->isArrow()); - Record.push_back(E->hasUnresolvedUsing()); - Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr); - Record.AddTypeRef(E->getBaseType()); + CurrentPackingBits.addBit(E->isArrow()); + CurrentPackingBits.addBit(E->hasUnresolvedUsing()); + CurrentPackingBits.addBit(!E->isImplicitAccess()); + if (!E->isImplicitAccess()) + Record.AddStmt(E->getBase()); + Record.AddSourceLocation(E->getOperatorLoc()); + + Record.AddTypeRef(E->getBaseType()); Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER; } void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); - Record.push_back(E->requiresADL()); - Record.push_back(E->isOverloaded()); + CurrentPackingBits.addBit(E->requiresADL()); + CurrentPackingBits.addBit(E->isOverloaded()); Record.AddDeclRef(E->getNamingClass()); Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP; } @@ -2059,12 +2156,12 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { VisitExpr(E); Record.AddDeclRef(E->getAssociatedDecl()); - Record.push_back(E->isReferenceParameter()); - Record.push_back(E->getIndex()); + CurrentPackingBits.addBit(E->isReferenceParameter()); + CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12); + CurrentPackingBits.addBit((bool)E->getPackIndex()); if (auto PackIndex = E->getPackIndex()) Record.push_back(*PackIndex + 1); - else - Record.push_back(0); + Record.AddSourceLocation(E->getNameLoc()); Record.AddStmt(E->getReplacement()); Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM; diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp index ce1265412655518d9f827cb601c9ef7e9e659521..c990ad138f89050182fbc847a575c4f5654e363a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -25,7 +25,7 @@ using namespace ento; namespace { class ArrayBoundChecker : public Checker { - mutable std::unique_ptr BT; + const BugType BT{this, "Out-of-bound array access"}; public: void checkLocation(SVal l, bool isLoad, const Stmt* S, @@ -65,16 +65,13 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS, if (!N) return; - if (!BT) - BT.reset(new BugType(this, "Out-of-bound array access")); - // FIXME: It would be nice to eventually make this diagnostic more clear, // e.g., by referencing the original declaration or by saying *why* this // reference is outside the range. // Generate a report for this bug. auto report = std::make_unique( - *BT, "Access out-of-bound array element (buffer overflow)", N); + BT, "Access out-of-bound array element (buffer overflow)", N); report->addRange(LoadS->getSourceRange()); C.emitReport(std::move(report)); diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index 5e25153a148fea10cbb3b0637d604093f2c23462..c72a97cc01e9142341c8669af3ff34c9d36b31de 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -44,7 +44,7 @@ namespace { class APIMisuse : public BugType { public: APIMisuse(const CheckerBase *checker, const char *name) - : BugType(checker, name, "API Misuse (Apple)") {} + : BugType(checker, name, categories::AppleAPIMisuse) {} }; } // end anonymous namespace diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 76f091562cd57f60180a77e99189f52fc51c09ff..66e080adb1382bcc273bb5161b93565a714a3d0c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -25,20 +25,31 @@ using namespace clang; using namespace ento; namespace { - class BlockInCriticalSectionChecker : public Checker { - - mutable IdentifierInfo *IILockGuard, *IIUniqueLock; - - CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn, - PthreadLockFn, PthreadTryLockFn, PthreadUnlockFn, - MtxLock, MtxTimedLock, MtxTryLock, MtxUnlock; - - StringRef ClassLockGuard, ClassUniqueLock; - - mutable bool IdentifierInfoInitialized; - - std::unique_ptr BlockInCritSectionBugType; + mutable IdentifierInfo *IILockGuard = nullptr; + mutable IdentifierInfo *IIUniqueLock = nullptr; + mutable bool IdentifierInfoInitialized = false; + + const CallDescription LockFn{{"lock"}}; + const CallDescription UnlockFn{{"unlock"}}; + const CallDescription SleepFn{{"sleep"}}; + const CallDescription GetcFn{{"getc"}}; + const CallDescription FgetsFn{{"fgets"}}; + const CallDescription ReadFn{{"read"}}; + const CallDescription RecvFn{{"recv"}}; + const CallDescription PthreadLockFn{{"pthread_mutex_lock"}}; + const CallDescription PthreadTryLockFn{{"pthread_mutex_trylock"}}; + const CallDescription PthreadUnlockFn{{"pthread_mutex_unlock"}}; + const CallDescription MtxLock{{"mtx_lock"}}; + const CallDescription MtxTimedLock{{"mtx_timedlock"}}; + const CallDescription MtxTryLock{{"mtx_trylock"}}; + const CallDescription MtxUnlock{{"mtx_unlock"}}; + + const llvm::StringLiteral ClassLockGuard{"lock_guard"}; + const llvm::StringLiteral ClassUniqueLock{"unique_lock"}; + + const BugType BlockInCritSectionBugType{ + this, "Call to blocking function in critical section", "Blocking Error"}; void initIdentifierInfo(ASTContext &Ctx) const; @@ -47,8 +58,6 @@ class BlockInCriticalSectionChecker : public Checker { CheckerContext &C) const; public: - BlockInCriticalSectionChecker(); - bool isBlockingFunction(const CallEvent &Call) const; bool isLockFunction(const CallEvent &Call) const; bool isUnlockFunction(const CallEvent &Call) const; @@ -63,22 +72,6 @@ public: REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned) -BlockInCriticalSectionChecker::BlockInCriticalSectionChecker() - : IILockGuard(nullptr), IIUniqueLock(nullptr), LockFn({"lock"}), - UnlockFn({"unlock"}), SleepFn({"sleep"}), GetcFn({"getc"}), - FgetsFn({"fgets"}), ReadFn({"read"}), RecvFn({"recv"}), - PthreadLockFn({"pthread_mutex_lock"}), - PthreadTryLockFn({"pthread_mutex_trylock"}), - PthreadUnlockFn({"pthread_mutex_unlock"}), MtxLock({"mtx_lock"}), - MtxTimedLock({"mtx_timedlock"}), MtxTryLock({"mtx_trylock"}), - MtxUnlock({"mtx_unlock"}), ClassLockGuard("lock_guard"), - ClassUniqueLock("unique_lock"), IdentifierInfoInitialized(false) { - // Initialize the bug type. - BlockInCritSectionBugType.reset( - new BugType(this, "Call to blocking function in critical section", - "Blocking Error")); -} - void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const { if (!IdentifierInfoInitialized) { /* In case of checking C code, or when the corresponding headers are not @@ -151,7 +144,7 @@ void BlockInCriticalSectionChecker::reportBlockInCritSection( llvm::raw_string_ostream os(msg); os << "Call to blocking function '" << Call.getCalleeIdentifier()->getName() << "' inside of critical section"; - auto R = std::make_unique(*BlockInCritSectionBugType, + auto R = std::make_unique(BlockInCritSectionBugType, os.str(), ErrNode); R->addRange(Call.getSourceRange()); R->markInteresting(BlockDescSym); diff --git a/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp index 361a4eed92210834dacdcfcd3d75b2cddab7fc1d..a09db6d2d0ec5ba323f1ebf1e93d7b60aaf072cf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp @@ -24,7 +24,7 @@ using namespace ento; namespace { class BoolAssignmentChecker : public Checker< check::Bind > { - mutable std::unique_ptr BT; + const BugType BT{this, "Assignment of a non-Boolean value"}; void emitReport(ProgramStateRef state, CheckerContext &C, bool IsTainted = false) const; @@ -36,12 +36,9 @@ namespace { void BoolAssignmentChecker::emitReport(ProgramStateRef state, CheckerContext &C, bool IsTainted) const { if (ExplodedNode *N = C.generateNonFatalErrorNode(state)) { - if (!BT) - BT.reset(new BugType(this, "Assignment of a non-Boolean value")); - StringRef Msg = IsTainted ? "Might assign a tainted non-Boolean value" : "Assignment of a non-Boolean value"; - C.emitReport(std::make_unique(*BT, Msg, N)); + C.emitReport(std::make_unique(BT, Msg, N)); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 31f5b03dcdeba80aa0427207ee3eee51092ffe49..b7b64c3da4f6c857bcf977d2ac290c431f022f8f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -121,7 +121,7 @@ public: const CallEvent *Call) const; using FnCheck = std::function; + const CallEvent &)>; CallDescriptionMap Callbacks = { {{CDF_MaybeBuiltin, {"memcpy"}, 3}, @@ -173,56 +173,53 @@ public: StdCopyBackward{{"std", "copy_backward"}, 3}; FnCheck identifyCall(const CallEvent &Call, CheckerContext &C) const; - void evalMemcpy(CheckerContext &C, const CallExpr *CE, CharKind CK) const; - void evalMempcpy(CheckerContext &C, const CallExpr *CE, CharKind CK) const; - void evalMemmove(CheckerContext &C, const CallExpr *CE, CharKind CK) const; - void evalBcopy(CheckerContext &C, const CallExpr *CE) const; - void evalCopyCommon(CheckerContext &C, const CallExpr *CE, + void evalMemcpy(CheckerContext &C, const CallEvent &Call, CharKind CK) const; + void evalMempcpy(CheckerContext &C, const CallEvent &Call, CharKind CK) const; + void evalMemmove(CheckerContext &C, const CallEvent &Call, CharKind CK) const; + void evalBcopy(CheckerContext &C, const CallEvent &Call) const; + void evalCopyCommon(CheckerContext &C, const CallEvent &Call, ProgramStateRef state, SizeArgExpr Size, DestinationArgExpr Dest, SourceArgExpr Source, bool Restricted, bool IsMempcpy, CharKind CK) const; - void evalMemcmp(CheckerContext &C, const CallExpr *CE, CharKind CK) const; + void evalMemcmp(CheckerContext &C, const CallEvent &Call, CharKind CK) const; - void evalstrLength(CheckerContext &C, const CallExpr *CE) const; - void evalstrnLength(CheckerContext &C, const CallExpr *CE) const; - void evalstrLengthCommon(CheckerContext &C, - const CallExpr *CE, + void evalstrLength(CheckerContext &C, const CallEvent &Call) const; + void evalstrnLength(CheckerContext &C, const CallEvent &Call) const; + void evalstrLengthCommon(CheckerContext &C, const CallEvent &Call, bool IsStrnlen = false) const; - void evalStrcpy(CheckerContext &C, const CallExpr *CE) const; - void evalStrncpy(CheckerContext &C, const CallExpr *CE) const; - void evalStpcpy(CheckerContext &C, const CallExpr *CE) const; - void evalStrlcpy(CheckerContext &C, const CallExpr *CE) const; - void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd, - bool IsBounded, ConcatFnKind appendK, + void evalStrcpy(CheckerContext &C, const CallEvent &Call) const; + void evalStrncpy(CheckerContext &C, const CallEvent &Call) const; + void evalStpcpy(CheckerContext &C, const CallEvent &Call) const; + void evalStrlcpy(CheckerContext &C, const CallEvent &Call) const; + void evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, + bool ReturnEnd, bool IsBounded, ConcatFnKind appendK, bool returnPtr = true) const; - void evalStrcat(CheckerContext &C, const CallExpr *CE) const; - void evalStrncat(CheckerContext &C, const CallExpr *CE) const; - void evalStrlcat(CheckerContext &C, const CallExpr *CE) const; + void evalStrcat(CheckerContext &C, const CallEvent &Call) const; + void evalStrncat(CheckerContext &C, const CallEvent &Call) const; + void evalStrlcat(CheckerContext &C, const CallEvent &Call) const; - void evalStrcmp(CheckerContext &C, const CallExpr *CE) const; - void evalStrncmp(CheckerContext &C, const CallExpr *CE) const; - void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const; - void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const; - void evalStrcmpCommon(CheckerContext &C, - const CallExpr *CE, - bool IsBounded = false, - bool IgnoreCase = false) const; + void evalStrcmp(CheckerContext &C, const CallEvent &Call) const; + void evalStrncmp(CheckerContext &C, const CallEvent &Call) const; + void evalStrcasecmp(CheckerContext &C, const CallEvent &Call) const; + void evalStrncasecmp(CheckerContext &C, const CallEvent &Call) const; + void evalStrcmpCommon(CheckerContext &C, const CallEvent &Call, + bool IsBounded = false, bool IgnoreCase = false) const; - void evalStrsep(CheckerContext &C, const CallExpr *CE) const; + void evalStrsep(CheckerContext &C, const CallEvent &Call) const; - void evalStdCopy(CheckerContext &C, const CallExpr *CE) const; - void evalStdCopyBackward(CheckerContext &C, const CallExpr *CE) const; - void evalStdCopyCommon(CheckerContext &C, const CallExpr *CE) const; - void evalMemset(CheckerContext &C, const CallExpr *CE) const; - void evalBzero(CheckerContext &C, const CallExpr *CE) const; + void evalStdCopy(CheckerContext &C, const CallEvent &Call) const; + void evalStdCopyBackward(CheckerContext &C, const CallEvent &Call) const; + void evalStdCopyCommon(CheckerContext &C, const CallEvent &Call) const; + void evalMemset(CheckerContext &C, const CallEvent &Call) const; + void evalBzero(CheckerContext &C, const CallEvent &Call) const; - void evalSprintf(CheckerContext &C, const CallExpr *CE) const; - void evalSnprintf(CheckerContext &C, const CallExpr *CE) const; - void evalSprintfCommon(CheckerContext &C, const CallExpr *CE, bool IsBounded, - bool IsBuiltin) const; + void evalSprintf(CheckerContext &C, const CallEvent &Call) const; + void evalSnprintf(CheckerContext &C, const CallEvent &Call) const; + void evalSprintfCommon(CheckerContext &C, const CallEvent &Call, + bool IsBounded, bool IsBuiltin) const; // Utility methods std::pair @@ -1291,7 +1288,7 @@ bool CStringChecker::memsetAux(const Expr *DstBuffer, SVal CharVal, // evaluation of individual function calls. //===----------------------------------------------------------------------===// -void CStringChecker::evalCopyCommon(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalCopyCommon(CheckerContext &C, const CallEvent &Call, ProgramStateRef state, SizeArgExpr Size, DestinationArgExpr Dest, SourceArgExpr Source, bool Restricted, @@ -1313,7 +1310,8 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, const CallExpr *CE, // If the size is zero, there won't be any actual memory access, so // just bind the return value to the destination buffer and return. if (stateZeroSize && !stateNonZeroSize) { - stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, destVal); + stateZeroSize = + stateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, destVal); C.addTransition(stateZeroSize); return; } @@ -1361,15 +1359,15 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, const CallExpr *CE, // If we don't know how much we copied, we can at least // conjure a return value for later. if (lastElement.isUnknown()) - lastElement = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, - C.blockCount()); + lastElement = C.getSValBuilder().conjureSymbolVal( + nullptr, Call.getOriginExpr(), LCtx, C.blockCount()); // The byte after the last byte copied is the return value. - state = state->BindExpr(CE, LCtx, lastElement); + state = state->BindExpr(Call.getOriginExpr(), LCtx, lastElement); } else { // All other copies return the destination buffer. // (Well, bcopy() has a void return type, but this won't hurt.) - state = state->BindExpr(CE, LCtx, destVal); + state = state->BindExpr(Call.getOriginExpr(), LCtx, destVal); } // Invalidate the destination (regular invalidation without pointer-escaping @@ -1391,69 +1389,69 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, const CallExpr *CE, } } -void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalMemcpy(CheckerContext &C, const CallEvent &Call, CharKind CK) const { // void *memcpy(void *restrict dst, const void *restrict src, size_t n); // The return value is the address of the destination buffer. - DestinationArgExpr Dest = {{CE->getArg(0), 0}}; - SourceArgExpr Src = {{CE->getArg(1), 1}}; - SizeArgExpr Size = {{CE->getArg(2), 2}}; + DestinationArgExpr Dest = {{Call.getArgExpr(0), 0}}; + SourceArgExpr Src = {{Call.getArgExpr(1), 1}}; + SizeArgExpr Size = {{Call.getArgExpr(2), 2}}; ProgramStateRef State = C.getState(); constexpr bool IsRestricted = true; constexpr bool IsMempcpy = false; - evalCopyCommon(C, CE, State, Size, Dest, Src, IsRestricted, IsMempcpy, CK); + evalCopyCommon(C, Call, State, Size, Dest, Src, IsRestricted, IsMempcpy, CK); } -void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalMempcpy(CheckerContext &C, const CallEvent &Call, CharKind CK) const { // void *mempcpy(void *restrict dst, const void *restrict src, size_t n); // The return value is a pointer to the byte following the last written byte. - DestinationArgExpr Dest = {{CE->getArg(0), 0}}; - SourceArgExpr Src = {{CE->getArg(1), 1}}; - SizeArgExpr Size = {{CE->getArg(2), 2}}; + DestinationArgExpr Dest = {{Call.getArgExpr(0), 0}}; + SourceArgExpr Src = {{Call.getArgExpr(1), 1}}; + SizeArgExpr Size = {{Call.getArgExpr(2), 2}}; constexpr bool IsRestricted = true; constexpr bool IsMempcpy = true; - evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy, - CK); + evalCopyCommon(C, Call, C.getState(), Size, Dest, Src, IsRestricted, + IsMempcpy, CK); } -void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalMemmove(CheckerContext &C, const CallEvent &Call, CharKind CK) const { // void *memmove(void *dst, const void *src, size_t n); // The return value is the address of the destination buffer. - DestinationArgExpr Dest = {{CE->getArg(0), 0}}; - SourceArgExpr Src = {{CE->getArg(1), 1}}; - SizeArgExpr Size = {{CE->getArg(2), 2}}; + DestinationArgExpr Dest = {{Call.getArgExpr(0), 0}}; + SourceArgExpr Src = {{Call.getArgExpr(1), 1}}; + SizeArgExpr Size = {{Call.getArgExpr(2), 2}}; constexpr bool IsRestricted = false; constexpr bool IsMempcpy = false; - evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy, - CK); + evalCopyCommon(C, Call, C.getState(), Size, Dest, Src, IsRestricted, + IsMempcpy, CK); } -void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalBcopy(CheckerContext &C, const CallEvent &Call) const { // void bcopy(const void *src, void *dst, size_t n); - SourceArgExpr Src{{CE->getArg(0), 0}}; - DestinationArgExpr Dest = {{CE->getArg(1), 1}}; - SizeArgExpr Size = {{CE->getArg(2), 2}}; + SourceArgExpr Src{{Call.getArgExpr(0), 0}}; + DestinationArgExpr Dest = {{Call.getArgExpr(1), 1}}; + SizeArgExpr Size = {{Call.getArgExpr(2), 2}}; constexpr bool IsRestricted = false; constexpr bool IsMempcpy = false; - evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy, - CharKind::Regular); + evalCopyCommon(C, Call, C.getState(), Size, Dest, Src, IsRestricted, + IsMempcpy, CharKind::Regular); } -void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalMemcmp(CheckerContext &C, const CallEvent &Call, CharKind CK) const { // int memcmp(const void *s1, const void *s2, size_t n); CurrentFunctionDescription = "memory comparison function"; - AnyArgExpr Left = {CE->getArg(0), 0}; - AnyArgExpr Right = {CE->getArg(1), 1}; - SizeArgExpr Size = {{CE->getArg(2), 2}}; + AnyArgExpr Left = {Call.getArgExpr(0), 0}; + AnyArgExpr Right = {Call.getArgExpr(1), 1}; + SizeArgExpr Size = {{Call.getArgExpr(2), 2}}; ProgramStateRef State = C.getState(); SValBuilder &Builder = C.getSValBuilder(); @@ -1471,7 +1469,8 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE, // have to check either of the buffers. if (stateZeroSize) { State = stateZeroSize; - State = State->BindExpr(CE, LCtx, Builder.makeZeroVal(CE->getType())); + State = State->BindExpr(Call.getOriginExpr(), LCtx, + Builder.makeZeroVal(Call.getResultType())); C.addTransition(State); } @@ -1497,8 +1496,8 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE, State = SameBuffer; State = CheckBufferAccess(C, State, Left, Size, AccessKind::read); if (State) { - State = - SameBuffer->BindExpr(CE, LCtx, Builder.makeZeroVal(CE->getType())); + State = SameBuffer->BindExpr(Call.getOriginExpr(), LCtx, + Builder.makeZeroVal(Call.getResultType())); C.addTransition(State); } return; @@ -1511,33 +1510,35 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE, State = CheckBufferAccess(C, State, Left, Size, AccessKind::read, CK); if (State) { // The return value is the comparison result, which we don't know. - SVal CmpV = Builder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); - State = State->BindExpr(CE, LCtx, CmpV); + SVal CmpV = Builder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, + C.blockCount()); + State = State->BindExpr(Call.getOriginExpr(), LCtx, CmpV); C.addTransition(State); } } } void CStringChecker::evalstrLength(CheckerContext &C, - const CallExpr *CE) const { + const CallEvent &Call) const { // size_t strlen(const char *s); - evalstrLengthCommon(C, CE, /* IsStrnlen = */ false); + evalstrLengthCommon(C, Call, /* IsStrnlen = */ false); } void CStringChecker::evalstrnLength(CheckerContext &C, - const CallExpr *CE) const { + const CallEvent &Call) const { // size_t strnlen(const char *s, size_t maxlen); - evalstrLengthCommon(C, CE, /* IsStrnlen = */ true); + evalstrLengthCommon(C, Call, /* IsStrnlen = */ true); } -void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalstrLengthCommon(CheckerContext &C, + const CallEvent &Call, bool IsStrnlen) const { CurrentFunctionDescription = "string length function"; ProgramStateRef state = C.getState(); const LocationContext *LCtx = C.getLocationContext(); if (IsStrnlen) { - const Expr *maxlenExpr = CE->getArg(1); + const Expr *maxlenExpr = Call.getArgExpr(1); SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); ProgramStateRef stateZeroSize, stateNonZeroSize; @@ -1547,8 +1548,8 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, // If the size can be zero, the result will be 0 in that case, and we don't // have to check the string itself. if (stateZeroSize) { - SVal zero = C.getSValBuilder().makeZeroVal(CE->getType()); - stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, zero); + SVal zero = C.getSValBuilder().makeZeroVal(Call.getResultType()); + stateZeroSize = stateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, zero); C.addTransition(stateZeroSize); } @@ -1561,7 +1562,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, } // Check that the string argument is non-null. - AnyArgExpr Arg = {CE->getArg(0), 0}; + AnyArgExpr Arg = {Call.getArgExpr(0), 0}; SVal ArgVal = state->getSVal(Arg.Expression, LCtx); state = checkNonNull(C, state, Arg, ArgVal); @@ -1584,7 +1585,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, // It's a little unfortunate to be getting this again, // but it's not that expensive... - const Expr *maxlenExpr = CE->getArg(1); + const Expr *maxlenExpr = Call.getArgExpr(1); SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); std::optional strLengthNL = strLength.getAs(); @@ -1613,8 +1614,8 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, // no guarantee the full string length will actually be returned. // All we know is the return value is the min of the string length // and the limit. This is better than nothing. - result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, - C.blockCount()); + result = C.getSValBuilder().conjureSymbolVal( + nullptr, Call.getOriginExpr(), LCtx, C.blockCount()); NonLoc resultNL = result.castAs(); if (strLengthNL) { @@ -1637,78 +1638,85 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, // If we don't know the length of the string, conjure a return // value, so it can be used in constraints, at least. if (result.isUnknown()) { - result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, - C.blockCount()); + result = C.getSValBuilder().conjureSymbolVal( + nullptr, Call.getOriginExpr(), LCtx, C.blockCount()); } } // Bind the return value. assert(!result.isUnknown() && "Should have conjured a value by now"); - state = state->BindExpr(CE, LCtx, result); + state = state->BindExpr(Call.getOriginExpr(), LCtx, result); C.addTransition(state); } -void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrcpy(CheckerContext &C, + const CallEvent &Call) const { // char *strcpy(char *restrict dst, const char *restrict src); - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ false, /* IsBounded = */ false, /* appendK = */ ConcatFnKind::none); } -void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrncpy(CheckerContext &C, + const CallEvent &Call) const { // char *strncpy(char *restrict dst, const char *restrict src, size_t n); - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ false, /* IsBounded = */ true, /* appendK = */ ConcatFnKind::none); } -void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStpcpy(CheckerContext &C, + const CallEvent &Call) const { // char *stpcpy(char *restrict dst, const char *restrict src); - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ true, /* IsBounded = */ false, /* appendK = */ ConcatFnKind::none); } -void CStringChecker::evalStrlcpy(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrlcpy(CheckerContext &C, + const CallEvent &Call) const { // size_t strlcpy(char *dest, const char *src, size_t size); - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ true, /* IsBounded = */ true, /* appendK = */ ConcatFnKind::none, /* returnPtr = */ false); } -void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrcat(CheckerContext &C, + const CallEvent &Call) const { // char *strcat(char *restrict s1, const char *restrict s2); - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ false, /* IsBounded = */ false, /* appendK = */ ConcatFnKind::strcat); } -void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrncat(CheckerContext &C, + const CallEvent &Call) const { // char *strncat(char *restrict s1, const char *restrict s2, size_t n); - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ false, /* IsBounded = */ true, /* appendK = */ ConcatFnKind::strcat); } -void CStringChecker::evalStrlcat(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrlcat(CheckerContext &C, + const CallEvent &Call) const { // size_t strlcat(char *dst, const char *src, size_t size); // It will append at most size - strlen(dst) - 1 bytes, // NULL-terminating the result. - evalStrcpyCommon(C, CE, + evalStrcpyCommon(C, Call, /* ReturnEnd = */ false, /* IsBounded = */ true, /* appendK = */ ConcatFnKind::strlcat, /* returnPtr = */ false); } -void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, bool ReturnEnd, bool IsBounded, ConcatFnKind appendK, bool returnPtr) const { @@ -1721,14 +1729,14 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, const LocationContext *LCtx = C.getLocationContext(); // Check that the destination is non-null. - DestinationArgExpr Dst = {{CE->getArg(0), 0}}; + DestinationArgExpr Dst = {{Call.getArgExpr(0), 0}}; SVal DstVal = state->getSVal(Dst.Expression, LCtx); state = checkNonNull(C, state, Dst, DstVal); if (!state) return; // Check that the source is non-null. - SourceArgExpr srcExpr = {{CE->getArg(1), 1}}; + SourceArgExpr srcExpr = {{Call.getArgExpr(1), 1}}; SVal srcVal = state->getSVal(srcExpr.Expression, LCtx); state = checkNonNull(C, state, srcExpr, srcVal); if (!state) @@ -1763,8 +1771,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, {srcExpr.Expression, srcExpr.ArgumentIndex}}; state = CheckOverlap( C, state, - (IsBounded ? SizeArgExpr{{CE->getArg(2), 2}} : SrcExprAsSizeDummy), Dst, - srcExpr); + (IsBounded ? SizeArgExpr{{Call.getArgExpr(2), 2}} : SrcExprAsSizeDummy), + Dst, srcExpr); if (!state) return; @@ -1772,7 +1780,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, // If the function is strncpy, strncat, etc... it is bounded. if (IsBounded) { // Get the max number of characters to copy. - SizeArgExpr lenExpr = {{CE->getArg(2), 2}}; + SizeArgExpr lenExpr = {{Call.getArgExpr(2), 2}}; SVal lenVal = state->getSVal(lenExpr.Expression, LCtx); // Protect against misdeclared strncpy(). @@ -1886,16 +1894,19 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, // If the size is known to be zero, we're done. if (StateZeroSize && !StateNonZeroSize) { if (returnPtr) { - StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, DstVal); + StateZeroSize = + StateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, DstVal); } else { if (appendK == ConcatFnKind::none) { // strlcpy returns strlen(src) - StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, strLength); + StateZeroSize = StateZeroSize->BindExpr(Call.getOriginExpr(), + LCtx, strLength); } else { // strlcat returns strlen(src) + strlen(dst) SVal retSize = svalBuilder.evalBinOp( state, BO_Add, strLength, dstStrLength, sizeTy); - StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, retSize); + StateZeroSize = + StateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, retSize); } } C.addTransition(StateZeroSize); @@ -1964,7 +1975,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, if (finalStrLength.isUnknown()) { // Try to get a "hypothetical" string length symbol, which we can later // set as a real value if that turns out to be the case. - finalStrLength = getCStringLength(C, state, CE, DstVal, true); + finalStrLength = + getCStringLength(C, state, Call.getOriginExpr(), DstVal, true); assert(!finalStrLength.isUndef()); if (std::optional finalStrLengthNL = @@ -2094,51 +2106,54 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, // If this is a stpcpy-style copy, but we were unable to check for a buffer // overflow, we still need a result. Conjure a return value. if (ReturnEnd && Result.isUnknown()) { - Result = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); + Result = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, + C.blockCount()); } } // Set the return value. - state = state->BindExpr(CE, LCtx, Result); + state = state->BindExpr(Call.getOriginExpr(), LCtx, Result); C.addTransition(state); } -void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrcmp(CheckerContext &C, + const CallEvent &Call) const { //int strcmp(const char *s1, const char *s2); - evalStrcmpCommon(C, CE, /* IsBounded = */ false, /* IgnoreCase = */ false); + evalStrcmpCommon(C, Call, /* IsBounded = */ false, /* IgnoreCase = */ false); } -void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrncmp(CheckerContext &C, + const CallEvent &Call) const { //int strncmp(const char *s1, const char *s2, size_t n); - evalStrcmpCommon(C, CE, /* IsBounded = */ true, /* IgnoreCase = */ false); + evalStrcmpCommon(C, Call, /* IsBounded = */ true, /* IgnoreCase = */ false); } void CStringChecker::evalStrcasecmp(CheckerContext &C, - const CallExpr *CE) const { + const CallEvent &Call) const { //int strcasecmp(const char *s1, const char *s2); - evalStrcmpCommon(C, CE, /* IsBounded = */ false, /* IgnoreCase = */ true); + evalStrcmpCommon(C, Call, /* IsBounded = */ false, /* IgnoreCase = */ true); } void CStringChecker::evalStrncasecmp(CheckerContext &C, - const CallExpr *CE) const { + const CallEvent &Call) const { //int strncasecmp(const char *s1, const char *s2, size_t n); - evalStrcmpCommon(C, CE, /* IsBounded = */ true, /* IgnoreCase = */ true); + evalStrcmpCommon(C, Call, /* IsBounded = */ true, /* IgnoreCase = */ true); } -void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, - bool IsBounded, bool IgnoreCase) const { +void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallEvent &Call, + bool IsBounded, bool IgnoreCase) const { CurrentFunctionDescription = "string comparison function"; ProgramStateRef state = C.getState(); const LocationContext *LCtx = C.getLocationContext(); // Check that the first string is non-null - AnyArgExpr Left = {CE->getArg(0), 0}; + AnyArgExpr Left = {Call.getArgExpr(0), 0}; SVal LeftVal = state->getSVal(Left.Expression, LCtx); state = checkNonNull(C, state, Left, LeftVal); if (!state) return; // Check that the second string is non-null. - AnyArgExpr Right = {CE->getArg(1), 1}; + AnyArgExpr Right = {Call.getArgExpr(1), 1}; SVal RightVal = state->getSVal(Right.Expression, LCtx); state = checkNonNull(C, state, Right, RightVal); if (!state) @@ -2169,8 +2184,9 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, // If the two arguments might be the same buffer, we know the result is 0, // and we only need to check one size. if (StSameBuf) { - StSameBuf = StSameBuf->BindExpr(CE, LCtx, - svalBuilder.makeZeroVal(CE->getType())); + StSameBuf = + StSameBuf->BindExpr(Call.getOriginExpr(), LCtx, + svalBuilder.makeZeroVal(Call.getResultType())); C.addTransition(StSameBuf); // If the two arguments are GUARANTEED to be the same, we're done! @@ -2190,8 +2206,8 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, const StringLiteral *RightStrLiteral = getCStringLiteral(C, state, Right.Expression, RightVal); bool canComputeResult = false; - SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, - C.blockCount()); + SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(), + LCtx, C.blockCount()); if (LeftStrLiteral && RightStrLiteral) { StringRef LeftStrRef = LeftStrLiteral->getString(); @@ -2199,7 +2215,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, if (IsBounded) { // Get the max number of characters to compare. - const Expr *lenExpr = CE->getArg(2); + const Expr *lenExpr = Call.getArgExpr(2); SVal lenVal = state->getSVal(lenExpr, LCtx); // If the length is known, we can get the right substrings. @@ -2231,10 +2247,10 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, // The strcmp function returns an integer greater than, equal to, or less // than zero, [c11, p7.24.4.2]. if (compareRes == 0) { - resultVal = svalBuilder.makeIntVal(compareRes, CE->getType()); + resultVal = svalBuilder.makeIntVal(compareRes, Call.getResultType()); } else { - DefinedSVal zeroVal = svalBuilder.makeIntVal(0, CE->getType()); + DefinedSVal zeroVal = svalBuilder.makeIntVal(0, Call.getResultType()); // Constrain strcmp's result range based on the result of StringRef's // comparison methods. BinaryOperatorKind op = (compareRes > 0) ? BO_GT : BO_LT; @@ -2247,20 +2263,21 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, } } - state = state->BindExpr(CE, LCtx, resultVal); + state = state->BindExpr(Call.getOriginExpr(), LCtx, resultVal); // Record this as a possible path. C.addTransition(state); } -void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalStrsep(CheckerContext &C, + const CallEvent &Call) const { // char *strsep(char **stringp, const char *delim); // Verify whether the search string parameter matches the return type. - SourceArgExpr SearchStrPtr = {{CE->getArg(0), 0}}; + SourceArgExpr SearchStrPtr = {{Call.getArgExpr(0), 0}}; QualType CharPtrTy = SearchStrPtr.Expression->getType()->getPointeeType(); - if (CharPtrTy.isNull() || - CE->getType().getUnqualifiedType() != CharPtrTy.getUnqualifiedType()) + if (CharPtrTy.isNull() || Call.getResultType().getUnqualifiedType() != + CharPtrTy.getUnqualifiedType()) return; CurrentFunctionDescription = "strsep()"; @@ -2275,7 +2292,7 @@ void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const { return; // Check that the delimiter string is non-null. - AnyArgExpr DelimStr = {CE->getArg(1), 1}; + AnyArgExpr DelimStr = {Call.getArgExpr(1), 1}; SVal DelimStrVal = State->getSVal(DelimStr.Expression, LCtx); State = checkNonNull(C, State, DelimStr, DelimStrVal); if (!State) @@ -2295,37 +2312,37 @@ void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const { // Overwrite the search string pointer. The new value is either an address // further along in the same string, or NULL if there are no more tokens. - State = State->bindLoc(*SearchStrLoc, - SVB.conjureSymbolVal(getTag(), - CE, - LCtx, - CharPtrTy, - C.blockCount()), - LCtx); + State = + State->bindLoc(*SearchStrLoc, + SVB.conjureSymbolVal(getTag(), Call.getOriginExpr(), + LCtx, CharPtrTy, C.blockCount()), + LCtx); } else { assert(SearchStrVal.isUnknown()); // Conjure a symbolic value. It's the best we can do. - Result = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); + Result = SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, + C.blockCount()); } // Set the return value, and finish. - State = State->BindExpr(CE, LCtx, Result); + State = State->BindExpr(Call.getOriginExpr(), LCtx, Result); C.addTransition(State); } // These should probably be moved into a C++ standard library checker. -void CStringChecker::evalStdCopy(CheckerContext &C, const CallExpr *CE) const { - evalStdCopyCommon(C, CE); +void CStringChecker::evalStdCopy(CheckerContext &C, + const CallEvent &Call) const { + evalStdCopyCommon(C, Call); } void CStringChecker::evalStdCopyBackward(CheckerContext &C, - const CallExpr *CE) const { - evalStdCopyCommon(C, CE); + const CallEvent &Call) const { + evalStdCopyCommon(C, Call); } void CStringChecker::evalStdCopyCommon(CheckerContext &C, - const CallExpr *CE) const { - if (!CE->getArg(2)->getType()->isPointerType()) + const CallEvent &Call) const { + if (!Call.getArgExpr(2)->getType()->isPointerType()) return; ProgramStateRef State = C.getState(); @@ -2338,7 +2355,7 @@ void CStringChecker::evalStdCopyCommon(CheckerContext &C, // _OutputIterator __result) // Invalidate the destination buffer - const Expr *Dst = CE->getArg(2); + const Expr *Dst = Call.getArgExpr(2); SVal DstVal = State->getSVal(Dst, LCtx); // FIXME: As we do not know how many items are copied, we also invalidate the // super region containing the target location. @@ -2347,19 +2364,21 @@ void CStringChecker::evalStdCopyCommon(CheckerContext &C, SValBuilder &SVB = C.getSValBuilder(); - SVal ResultVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); - State = State->BindExpr(CE, LCtx, ResultVal); + SVal ResultVal = + SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, C.blockCount()); + State = State->BindExpr(Call.getOriginExpr(), LCtx, ResultVal); C.addTransition(State); } -void CStringChecker::evalMemset(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalMemset(CheckerContext &C, + const CallEvent &Call) const { // void *memset(void *s, int c, size_t n); CurrentFunctionDescription = "memory set function"; - DestinationArgExpr Buffer = {{CE->getArg(0), 0}}; - AnyArgExpr CharE = {CE->getArg(1), 1}; - SizeArgExpr Size = {{CE->getArg(2), 2}}; + DestinationArgExpr Buffer = {{Call.getArgExpr(0), 0}}; + AnyArgExpr CharE = {Call.getArgExpr(1), 1}; + SizeArgExpr Size = {{Call.getArgExpr(2), 2}}; ProgramStateRef State = C.getState(); @@ -2377,7 +2396,7 @@ void CStringChecker::evalMemset(CheckerContext &C, const CallExpr *CE) const { // If the size is zero, there won't be any actual memory access, so // just bind the return value to the buffer and return. if (ZeroSize && !NonZeroSize) { - ZeroSize = ZeroSize->BindExpr(CE, LCtx, BufferPtrVal); + ZeroSize = ZeroSize->BindExpr(Call.getOriginExpr(), LCtx, BufferPtrVal); C.addTransition(ZeroSize); return; } @@ -2399,15 +2418,15 @@ void CStringChecker::evalMemset(CheckerContext &C, const CallExpr *CE) const { Size.Expression, C, State)) return; - State = State->BindExpr(CE, LCtx, BufferPtrVal); + State = State->BindExpr(Call.getOriginExpr(), LCtx, BufferPtrVal); C.addTransition(State); } -void CStringChecker::evalBzero(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalBzero(CheckerContext &C, const CallEvent &Call) const { CurrentFunctionDescription = "memory clearance function"; - DestinationArgExpr Buffer = {{CE->getArg(0), 0}}; - SizeArgExpr Size = {{CE->getArg(1), 1}}; + DestinationArgExpr Buffer = {{Call.getArgExpr(0), 0}}; + SizeArgExpr Size = {{Call.getArgExpr(1), 1}}; SVal Zero = C.getSValBuilder().makeZeroVal(C.getASTContext().IntTy); ProgramStateRef State = C.getState(); @@ -2446,24 +2465,29 @@ void CStringChecker::evalBzero(CheckerContext &C, const CallExpr *CE) const { C.addTransition(State); } -void CStringChecker::evalSprintf(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalSprintf(CheckerContext &C, + const CallEvent &Call) const { CurrentFunctionDescription = "'sprintf'"; + const auto *CE = cast(Call.getOriginExpr()); bool IsBI = CE->getBuiltinCallee() == Builtin::BI__builtin___sprintf_chk; - evalSprintfCommon(C, CE, /* IsBounded */ false, IsBI); + evalSprintfCommon(C, Call, /* IsBounded */ false, IsBI); } -void CStringChecker::evalSnprintf(CheckerContext &C, const CallExpr *CE) const { +void CStringChecker::evalSnprintf(CheckerContext &C, + const CallEvent &Call) const { CurrentFunctionDescription = "'snprintf'"; + const auto *CE = cast(Call.getOriginExpr()); bool IsBI = CE->getBuiltinCallee() == Builtin::BI__builtin___snprintf_chk; - evalSprintfCommon(C, CE, /* IsBounded */ true, IsBI); + evalSprintfCommon(C, Call, /* IsBounded */ true, IsBI); } -void CStringChecker::evalSprintfCommon(CheckerContext &C, const CallExpr *CE, +void CStringChecker::evalSprintfCommon(CheckerContext &C, const CallEvent &Call, bool IsBounded, bool IsBuiltin) const { ProgramStateRef State = C.getState(); - DestinationArgExpr Dest = {{CE->getArg(0), 0}}; + const auto *CE = cast(Call.getOriginExpr()); + DestinationArgExpr Dest = {{Call.getArgExpr(0), 0}}; - const auto NumParams = CE->getCalleeDecl()->getAsFunction()->getNumParams(); + const auto NumParams = Call.parameters().size(); assert(CE->getNumArgs() >= NumParams); const auto AllArguments = @@ -2483,7 +2507,7 @@ void CStringChecker::evalSprintfCommon(CheckerContext &C, const CallExpr *CE, {Source.Expression, Source.ArgumentIndex}}; State = CheckOverlap( C, State, - (IsBounded ? SizeArgExpr{{CE->getArg(1), 1}} : SrcExprAsSizeDummy), + (IsBounded ? SizeArgExpr{{Call.getArgExpr(1), 1}} : SrcExprAsSizeDummy), Dest, Source); if (!State) return; @@ -2536,8 +2560,8 @@ bool CStringChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { return false; // Check and evaluate the call. - const auto *CE = cast(Call.getOriginExpr()); - Callback(this, C, CE); + assert(isa(Call.getOriginExpr())); + Callback(this, C, Call); // If the evaluate call resulted in no change, chain to the next eval call // handler. diff --git a/clang/lib/StaticAnalyzer/Checkers/CXXDeleteChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CXXDeleteChecker.cpp index eb265f4dde68bc2691aa1d5bd92e84b617ac9dd3..b4dee1e300e886369d43c374d63b72e4aa6d88cb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CXXDeleteChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CXXDeleteChecker.cpp @@ -31,6 +31,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -65,7 +66,8 @@ public: }; class DeleteWithNonVirtualDtorChecker : public CXXDeleteChecker { - mutable std::unique_ptr BT; + const BugType BT{ + this, "Destruction of a polymorphic object with no virtual destructor"}; void checkTypedDeleteExpr(const CXXDeleteExpr *DE, CheckerContext &C, @@ -74,7 +76,8 @@ class DeleteWithNonVirtualDtorChecker : public CXXDeleteChecker { }; class CXXArrayDeleteChecker : public CXXDeleteChecker { - mutable std::unique_ptr BT; + const BugType BT{this, + "Deleting an array of polymorphic objects is undefined"}; void checkTypedDeleteExpr(const CXXDeleteExpr *DE, CheckerContext &C, @@ -123,17 +126,10 @@ void DeleteWithNonVirtualDtorChecker::checkTypedDeleteExpr( if (!DerivedClass->isDerivedFrom(BaseClass)) return; - if (!BT) - BT.reset(new BugType(this, - "Destruction of a polymorphic object with no " - "virtual destructor", - "Logic error")); - ExplodedNode *N = C.generateNonFatalErrorNode(); if (!N) return; - auto R = - std::make_unique(*BT, BT->getDescription(), N); + auto R = std::make_unique(BT, BT.getDescription(), N); // Mark region of problematic base class for later use in the BugVisitor. R->markInteresting(BaseClassRegion); @@ -160,12 +156,6 @@ void CXXArrayDeleteChecker::checkTypedDeleteExpr( if (!DerivedClass->isDerivedFrom(BaseClass)) return; - if (!BT) - BT.reset(new BugType(this, - "Deleting an array of polymorphic objects " - "is undefined", - "Logic error")); - ExplodedNode *N = C.generateNonFatalErrorNode(); if (!N) return; @@ -182,7 +172,7 @@ void CXXArrayDeleteChecker::checkTypedDeleteExpr( << SourceType.getAsString(C.getASTContext().getPrintingPolicy()) << "' is undefined"; - auto R = std::make_unique(*BT, OS.str(), N); + auto R = std::make_unique(BT, OS.str(), N); // Mark region of problematic base class for later use in the BugVisitor. R->markInteresting(BaseClassRegion); diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index ea74256935ca8796c0f3ff84e185a7ce38fe6947..f2e1f69c32cfdcfa7f12d1d197fc86b4a82e647d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -125,9 +125,8 @@ private: if (!BT) BT.reset(new BugType(OriginalName, desc)); } - bool uninitRefOrPointer(CheckerContext &C, const SVal &V, - SourceRange ArgRange, const Expr *ArgEx, - std::unique_ptr &BT, + bool uninitRefOrPointer(CheckerContext &C, SVal V, SourceRange ArgRange, + const Expr *ArgEx, std::unique_ptr &BT, const ParmVarDecl *ParamDecl, const char *BD, int ArgumentNumber) const; }; @@ -185,7 +184,7 @@ static void describeUninitializedArgumentInCall(const CallEvent &Call, } bool CallAndMessageChecker::uninitRefOrPointer( - CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx, + CheckerContext &C, SVal V, SourceRange ArgRange, const Expr *ArgEx, std::unique_ptr &BT, const ParmVarDecl *ParamDecl, const char *BD, int ArgumentNumber) const { @@ -263,7 +262,7 @@ public: if (Find(FR)) return true; } else { - const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); + SVal V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); if (V.isUndef()) return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp index d1d4f3baf6a852cd6210284ac58b8c5995a4b632..a50772f881f7d0fdabf0427c012fa0fe329331a3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp @@ -24,7 +24,7 @@ using namespace ento; namespace { class CastSizeChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT; + const BugType BT{this, "Cast region with wrong size."}; public: void checkPreStmt(const CastExpr *CE, CheckerContext &C) const; @@ -131,12 +131,10 @@ void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const { return; if (ExplodedNode *errorNode = C.generateErrorNode()) { - if (!BT) - BT.reset(new BugType(this, "Cast region with wrong size.")); constexpr llvm::StringLiteral Msg = "Cast a region whose size is not a multiple of the destination type " "size."; - auto R = std::make_unique(*BT, Msg, errorNode); + auto R = std::make_unique(BT, Msg, errorNode); R->addRange(CE->getSourceRange()); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index bd6655cc1e3fa352daf2e3a2145f5a8357cd36b2..978bc0bb082f80ff3f14d24b184826ae8b13a4ff 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -99,18 +99,23 @@ class ObjCDeallocChecker check::PointerEscape, check::PreStmt> { - mutable IdentifierInfo *NSObjectII, *SenTestCaseII, *XCTestCaseII, - *Block_releaseII, *CIFilterII; - - mutable Selector DeallocSel, ReleaseSel; - - std::unique_ptr MissingReleaseBugType; - std::unique_ptr ExtraReleaseBugType; - std::unique_ptr MistakenDeallocBugType; + mutable const IdentifierInfo *NSObjectII = nullptr; + mutable const IdentifierInfo *SenTestCaseII = nullptr; + mutable const IdentifierInfo *XCTestCaseII = nullptr; + mutable const IdentifierInfo *Block_releaseII = nullptr; + mutable const IdentifierInfo *CIFilterII = nullptr; + + mutable Selector DeallocSel; + mutable Selector ReleaseSel; + + const BugType MissingReleaseBugType{this, "Missing ivar release (leak)", + categories::MemoryRefCount}; + const BugType ExtraReleaseBugType{this, "Extra ivar release", + categories::MemoryRefCount}; + const BugType MistakenDeallocBugType{this, "Mistaken dealloc", + categories::MemoryRefCount}; public: - ObjCDeallocChecker(); - void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& Mgr, BugReporter &BR) const; void checkBeginFunction(CheckerContext &Ctx) const; @@ -579,7 +584,7 @@ void ObjCDeallocChecker::diagnoseMissingReleases(CheckerContext &C) const { OS << " by a synthesized property but not released" " before '[super dealloc]'"; - auto BR = std::make_unique(*MissingReleaseBugType, + auto BR = std::make_unique(MissingReleaseBugType, OS.str(), ErrNode); C.emitReport(std::move(BR)); } @@ -701,7 +706,7 @@ bool ObjCDeallocChecker::diagnoseExtraRelease(SymbolRef ReleasedValue, OS << " property but was released in 'dealloc'"; } - auto BR = std::make_unique(*ExtraReleaseBugType, + auto BR = std::make_unique(ExtraReleaseBugType, OS.str(), ErrNode); BR->addRange(M.getOriginExpr()->getSourceRange()); @@ -743,7 +748,7 @@ bool ObjCDeallocChecker::diagnoseMistakenDealloc(SymbolRef DeallocedValue, OS << "'" << *PropImpl->getPropertyIvarDecl() << "' should be released rather than deallocated"; - auto BR = std::make_unique(*MistakenDeallocBugType, + auto BR = std::make_unique(MistakenDeallocBugType, OS.str(), ErrNode); BR->addRange(M.getOriginExpr()->getSourceRange()); @@ -752,23 +757,6 @@ bool ObjCDeallocChecker::diagnoseMistakenDealloc(SymbolRef DeallocedValue, return true; } -ObjCDeallocChecker::ObjCDeallocChecker() - : NSObjectII(nullptr), SenTestCaseII(nullptr), XCTestCaseII(nullptr), - Block_releaseII(nullptr), CIFilterII(nullptr) { - - MissingReleaseBugType.reset( - new BugType(this, "Missing ivar release (leak)", - categories::MemoryRefCount)); - - ExtraReleaseBugType.reset( - new BugType(this, "Extra ivar release", - categories::MemoryRefCount)); - - MistakenDeallocBugType.reset( - new BugType(this, "Mistaken dealloc", - categories::MemoryRefCount)); -} - void ObjCDeallocChecker::initIdentifierInfoAndSelectors( ASTContext &Ctx) const { if (NSObjectII) @@ -1045,8 +1033,8 @@ bool ObjCDeallocChecker::isReleasedByCIFilterDealloc( StringRef IvarName = PropImpl->getPropertyIvarDecl()->getName(); const char *ReleasePrefix = "input"; - if (!(PropName.startswith(ReleasePrefix) || - IvarName.startswith(ReleasePrefix))) { + if (!(PropName.starts_with(ReleasePrefix) || + IvarName.starts_with(ReleasePrefix))) { return false; } diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index dbba12bb4355c3a48b20a523d75f44b232e4deea..ce05d2d3c90585f99e69aed781968bbb55885e4e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -140,8 +140,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { if (!II) // if no identifier, not a simple C function return; StringRef Name = II->getName(); - if (Name.startswith("__builtin_")) - Name = Name.substr(10); + Name.consume_front("__builtin_"); // Set the evaluation function by switching on the callee name. FnCheck evalFunction = @@ -763,8 +762,7 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE, enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 }; StringRef Name = FD->getIdentifier()->getName(); - if (Name.startswith("__builtin_")) - Name = Name.substr(10); + Name.consume_front("__builtin_"); int ArgIndex = llvm::StringSwitch(Name) diff --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp index 9e11d8d9ecbc3ccd3c2a9f1bcd0e406100925f55..be7be15022d360d665b63777cbb7a588cdd3f9e5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp @@ -41,7 +41,7 @@ bool isRootChanged(intptr_t k) { return k == ROOT_CHANGED; } // bug<--foo()-- JAIL_ENTERED<--foo()-- class ChrootChecker : public Checker { // This bug refers to possibly break out of a chroot() jail. - mutable std::unique_ptr BT_BreakJail; + const BugType BT_BreakJail{this, "Break out of jail"}; const CallDescription Chroot{{"chroot"}, 1}, Chdir{{"chdir"}, 1}; @@ -124,12 +124,10 @@ void ChrootChecker::checkPreCall(const CallEvent &Call, if (k) if (isRootChanged((intptr_t) *k)) if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - if (!BT_BreakJail) - BT_BreakJail.reset(new BugType(this, "Break out of jail")); constexpr llvm::StringLiteral Msg = "No call of chdir(\"/\") immediately after chroot"; C.emitReport( - std::make_unique(*BT_BreakJail, Msg, N)); + std::make_unique(BT_BreakJail, Msg, N)); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 0e21ea7e90c9c216923b6a865fe88f3c4aa7163f..6692a45a09f776dfd59f1860b97c3d75e4608514 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -35,7 +35,8 @@ public: private: mutable CloneDetector Detector; - mutable std::unique_ptr BT_Exact, BT_Suspicious; + const BugType BT_Exact{this, "Exact code clone", "Code clone"}; + const BugType BT_Suspicious{this, "Suspicious code clone", "Code clone"}; public: void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, @@ -107,15 +108,11 @@ static PathDiagnosticLocation makeLocation(const StmtSequence &S, void CloneChecker::reportClones( BugReporter &BR, AnalysisManager &Mgr, std::vector &CloneGroups) const { - - if (!BT_Exact) - BT_Exact.reset(new BugType(this, "Exact code clone", "Code clone")); - for (const CloneDetector::CloneGroup &Group : CloneGroups) { // We group the clones by printing the first as a warning and all others // as a note. auto R = std::make_unique( - *BT_Exact, "Duplicate code detected", makeLocation(Group.front(), Mgr)); + BT_Exact, "Duplicate code detected", makeLocation(Group.front(), Mgr)); R->addRange(Group.front().getSourceRange()); for (unsigned i = 1; i < Group.size(); ++i) @@ -154,10 +151,6 @@ void CloneChecker::reportSuspiciousClones( } } - if (!BT_Suspicious) - BT_Suspicious.reset( - new BugType(this, "Suspicious code clone", "Code clone")); - ASTContext &ACtx = BR.getContext(); SourceManager &SM = ACtx.getSourceManager(); AnalysisDeclContext *ADC = @@ -170,7 +163,7 @@ void CloneChecker::reportSuspiciousClones( // Think how to perform more accurate suggestions? auto R = std::make_unique( - *BT_Suspicious, + BT_Suspicious, "Potential copy-paste error; did you really mean to use '" + Pair.FirstCloneInfo.Variable->getNameAsString() + "' here?", PathDiagnosticLocation::createBegin(Pair.FirstCloneInfo.Mention, SM, diff --git a/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp index 8b34b41bab21c3191156b7a225c187ae4c620167..eca8d3cc072292e14686db234c095405657e2231 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp @@ -42,7 +42,7 @@ public: void checkPreStmt(const ImplicitCastExpr *Cast, CheckerContext &C) const; private: - mutable std::unique_ptr BT; + const BugType BT{this, "Conversion"}; bool isLossOfPrecision(const ImplicitCastExpr *Cast, QualType DestType, CheckerContext &C) const; @@ -126,11 +126,8 @@ void ConversionChecker::checkPreStmt(const ImplicitCastExpr *Cast, void ConversionChecker::reportBug(ExplodedNode *N, const Expr *E, CheckerContext &C, const char Msg[]) const { - if (!BT) - BT.reset(new BugType(this, "Conversion")); - // Generate a report for this bug. - auto R = std::make_unique(*BT, Msg, N); + auto R = std::make_unique(BT, Msg, N); bugreporter::trackExpressionValue(N, E, *R); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index 5f44c9476928dd827ccff91267835437f165be85..86f446fc411ca2bdccd1e044f60f7525790ad133 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -183,7 +183,7 @@ public: // Files autogenerated by DriverKit IIG contain some dead stores that // we don't want to report. - if (Data.startswith("/* iig")) + if (Data.starts_with("/* iig")) return true; return false; diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp index 832bb78c48035c394dcde75932bce7a8df2c0064..97f769b1c451f6e2e4065f7dd7cba4ef0b397604 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp @@ -28,7 +28,8 @@ namespace { class DebugContainerModeling : public Checker { - std::unique_ptr DebugMsgBugType; + const BugType DebugMsgBugType{this, "Checking analyzer assumptions", "debug", + /*SuppressOnSink=*/true}; template void analyzerContainerDataField(const CallExpr *CE, CheckerContext &C, @@ -48,19 +49,11 @@ class DebugContainerModeling }; public: - DebugContainerModeling(); - bool evalCall(const CallEvent &Call, CheckerContext &C) const; }; } //namespace -DebugContainerModeling::DebugContainerModeling() { - DebugMsgBugType.reset( - new BugType(this, "Checking analyzer assumptions", "debug", - /*SuppressOnSink=*/true)); -} - bool DebugContainerModeling::evalCall(const CallEvent &Call, CheckerContext &C) const { const auto *CE = dyn_cast_or_null(Call.getOriginExpr()); @@ -137,8 +130,8 @@ ExplodedNode *DebugContainerModeling::reportDebugMsg(llvm::StringRef Msg, return nullptr; auto &BR = C.getBugReporter(); - BR.emitReport(std::make_unique(*DebugMsgBugType, - Msg, N)); + BR.emitReport( + std::make_unique(DebugMsgBugType, Msg, N)); return N; } diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp index d05298b42c55cd0e54c4505231e45bea8575f207..ff479c7b0ac89dc00e8d1e66891bbb4e960d5c4b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp @@ -28,7 +28,8 @@ namespace { class DebugIteratorModeling : public Checker { - std::unique_ptr DebugMsgBugType; + const BugType DebugMsgBugType{this, "Checking analyzer assumptions", "debug", + /*SuppressOnSink=*/true}; template void analyzerIteratorDataField(const CallExpr *CE, CheckerContext &C, @@ -51,19 +52,11 @@ class DebugIteratorModeling }; public: - DebugIteratorModeling(); - bool evalCall(const CallEvent &Call, CheckerContext &C) const; }; } //namespace -DebugIteratorModeling::DebugIteratorModeling() { - DebugMsgBugType.reset( - new BugType(this, "Checking analyzer assumptions", "debug", - /*SuppressOnSink=*/true)); -} - bool DebugIteratorModeling::evalCall(const CallEvent &Call, CheckerContext &C) const { const auto *CE = dyn_cast_or_null(Call.getOriginExpr()); @@ -131,8 +124,8 @@ ExplodedNode *DebugIteratorModeling::reportDebugMsg(llvm::StringRef Msg, return nullptr; auto &BR = C.getBugReporter(); - BR.emitReport(std::make_unique(*DebugMsgBugType, - Msg, N)); + BR.emitReport( + std::make_unique(DebugMsgBugType, Msg, N)); return N; } diff --git a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index 5331d9574743fb63b606fd4cdf15c03945ad1fe7..5496f087447fbeb58c5571c51efffce2ba1c28b7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -14,6 +14,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Checkers/Taint.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -25,8 +26,8 @@ using namespace taint; namespace { class DivZeroChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT; - mutable std::unique_ptr TaintBT; + const BugType BT{this, "Division by zero"}; + const BugType TaintBT{this, "Division by zero", categories::TaintedData}; void reportBug(StringRef Msg, ProgramStateRef StateZero, CheckerContext &C) const; void reportTaintBug(StringRef Msg, ProgramStateRef StateZero, @@ -48,10 +49,7 @@ static const Expr *getDenomExpr(const ExplodedNode *N) { void DivZeroChecker::reportBug(StringRef Msg, ProgramStateRef StateZero, CheckerContext &C) const { if (ExplodedNode *N = C.generateErrorNode(StateZero)) { - if (!BT) - BT.reset(new BugType(this, "Division by zero", categories::LogicError)); - - auto R = std::make_unique(*BT, Msg, N); + auto R = std::make_unique(BT, Msg, N); bugreporter::trackExpressionValue(N, getDenomExpr(N), *R); C.emitReport(std::move(R)); } @@ -61,11 +59,7 @@ void DivZeroChecker::reportTaintBug( StringRef Msg, ProgramStateRef StateZero, CheckerContext &C, llvm::ArrayRef TaintedSyms) const { if (ExplodedNode *N = C.generateErrorNode(StateZero)) { - if (!TaintBT) - TaintBT.reset( - new BugType(this, "Division by zero", categories::TaintedData)); - - auto R = std::make_unique(*TaintBT, Msg, N); + auto R = std::make_unique(TaintBT, Msg, N); bugreporter::trackExpressionValue(N, getDenomExpr(N), *R); for (auto Sym : TaintedSyms) R->markInteresting(Sym); diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp index dbc930d7d37b7c6a95f5f6f8f150b945f5abf4cf..0ad307d3ebd50409da75728178c8a6dbf0c9cba1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp @@ -30,12 +30,7 @@ using namespace ento; namespace { class DynamicTypeChecker : public Checker> { - mutable std::unique_ptr BT; - void initBugType() const { - if (!BT) - BT.reset( - new BugType(this, "Dynamic and static type mismatch", "Type Error")); - } + const BugType BT{this, "Dynamic and static type mismatch", "Type Error"}; class DynamicTypeBugVisitor : public BugReporterVisitor { public: @@ -70,7 +65,6 @@ void DynamicTypeChecker::reportTypeError(QualType DynamicType, const MemRegion *Reg, const Stmt *ReportedNode, CheckerContext &C) const { - initBugType(); SmallString<192> Buf; llvm::raw_svector_ostream OS(Buf); OS << "Object has a dynamic type '"; @@ -81,7 +75,7 @@ void DynamicTypeChecker::reportTypeError(QualType DynamicType, llvm::Twine()); OS << "'"; auto R = std::make_unique( - *BT, OS.str(), C.generateNonFatalErrorNode()); + BT, OS.str(), C.generateNonFatalErrorNode()); R->markInteresting(Reg); R->addVisitor(std::make_unique(Reg)); R->addRange(ReportedNode->getSourceRange()); diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp index 7c51673422a0a2b2ddbbdc8303e3bda09b56ed36..0fa20428c1b5600799dc62ab1524055058dd6b31 100644 --- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -60,7 +60,7 @@ public: // Being conservative, it does not warn if there is slight possibility the // value can be matching. class EnumCastOutOfRangeChecker : public Checker> { - mutable std::unique_ptr EnumValueCastOutOfRange; + const BugType EnumValueCastOutOfRange{this, "Enum cast out of range"}; void reportWarning(CheckerContext &C, const CastExpr *CE, const EnumDecl *E) const; @@ -85,10 +85,6 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C, const EnumDecl *E) const { assert(E && "valid EnumDecl* is expected"); if (const ExplodedNode *N = C.generateNonFatalErrorNode()) { - if (!EnumValueCastOutOfRange) - EnumValueCastOutOfRange.reset( - new BugType(this, "Enum cast out of range")); - std::string ValueStr = "", NameStr = "the enum"; // Try to add details to the message: @@ -105,7 +101,7 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C, "not in the valid range of values for {1}", ValueStr, NameStr); - auto BR = std::make_unique(*EnumValueCastOutOfRange, + auto BR = std::make_unique(EnumValueCastOutOfRange, Msg, N); bugreporter::trackExpressionValue(N, CE->getSubExpr(), *BR); BR->addNote("enum declared here", diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp index 2c7bacac33a687f8e81cc1cb7768f3fc582e1966..3096999e9fd16310781cfd14f325cd16b324ec3a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -25,7 +25,7 @@ using namespace ento; namespace { class ExprInspectionChecker : public Checker { - mutable std::unique_ptr BT; + const BugType BT{this, "Checking analyzer assumptions", "debug"}; // These stats are per-analysis, not per-branch, hence they shouldn't // stay inside the program state. @@ -176,11 +176,7 @@ ExprInspectionChecker::reportBug(llvm::StringRef Msg, BugReporter &BR, std::optional ExprVal) const { if (!N) return nullptr; - - if (!BT) - BT.reset(new BugType(this, "Checking analyzer assumptions", "debug")); - - auto R = std::make_unique(*BT, Msg, N); + auto R = std::make_unique(BT, Msg, N); if (ExprVal) { R->markInteresting(*ExprVal); } diff --git a/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp index 2ee201b640089d1474f65fed02a5788a5864686b..7aefcdc6d358aaf49bf2f02d5f65538a87f3c591 100644 --- a/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp @@ -24,7 +24,7 @@ using namespace ento; namespace { class FixedAddressChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT; + const BugType BT{this, "Use fixed address"}; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; @@ -50,12 +50,10 @@ void FixedAddressChecker::checkPreStmt(const BinaryOperator *B, if (ExplodedNode *N = C.generateNonFatalErrorNode()) { // FIXME: improve grammar in the following strings: - if (!BT) - BT.reset(new BugType(this, "Use fixed address")); constexpr llvm::StringLiteral Msg = "Using a fixed address is not portable because that address will " "probably not be valid in all environments or platforms."; - auto R = std::make_unique(*BT, Msg, N); + auto R = std::make_unique(BT, Msg, N); R->addRange(B->getRHS()->getSourceRange()); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp index 8e02ef74c66863ef9ebe2a42ade8946681070eed..5637941a58f0260053fc4331563fab1a3ef61f7e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp @@ -73,7 +73,7 @@ decltype(auto) bindAssignmentToDecl(const char *DeclName) { static bool isTest(const Decl *D) { if (const auto* ND = dyn_cast(D)) { std::string DeclName = ND->getNameAsString(); - if (StringRef(DeclName).startswith("test")) + if (StringRef(DeclName).starts_with("test")) return true; } if (const auto *OD = dyn_cast(D)) { diff --git a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp index 6955ba11a28ff75de841da17cbca30e19cea96a0..3f5856a3efbe75ed34a363ffa00731b87430f45e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp @@ -31,14 +31,14 @@ class InvalidatedIteratorChecker check::PreStmt, check::PreStmt> { - std::unique_ptr InvalidatedBugType; + const BugType InvalidatedBugType{this, "Iterator invalidated", + "Misuse of STL APIs"}; - void verifyAccess(CheckerContext &C, const SVal &Val) const; - void reportBug(const StringRef &Message, const SVal &Val, - CheckerContext &C, ExplodedNode *ErrNode) const; -public: - InvalidatedIteratorChecker(); + void verifyAccess(CheckerContext &C, SVal Val) const; + void reportBug(StringRef Message, SVal Val, CheckerContext &C, + ExplodedNode *ErrNode) const; +public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const; void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; @@ -49,11 +49,6 @@ public: } //namespace -InvalidatedIteratorChecker::InvalidatedIteratorChecker() { - InvalidatedBugType.reset( - new BugType(this, "Iterator invalidated", "Misuse of STL APIs")); -} - void InvalidatedIteratorChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { // Check for access of invalidated position @@ -114,7 +109,8 @@ void InvalidatedIteratorChecker::checkPreStmt(const MemberExpr *ME, verifyAccess(C, BaseVal); } -void InvalidatedIteratorChecker::verifyAccess(CheckerContext &C, const SVal &Val) const { +void InvalidatedIteratorChecker::verifyAccess(CheckerContext &C, + SVal Val) const { auto State = C.getState(); const auto *Pos = getIteratorPosition(State, Val); if (Pos && !Pos->isValid()) { @@ -126,11 +122,11 @@ void InvalidatedIteratorChecker::verifyAccess(CheckerContext &C, const SVal &Val } } -void InvalidatedIteratorChecker::reportBug(const StringRef &Message, - const SVal &Val, CheckerContext &C, +void InvalidatedIteratorChecker::reportBug(StringRef Message, SVal Val, + CheckerContext &C, ExplodedNode *ErrNode) const { - auto R = std::make_unique(*InvalidatedBugType, - Message, ErrNode); + auto R = std::make_unique(InvalidatedBugType, Message, + ErrNode); R->markInteresting(Val); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp b/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp index 90047a2899a7d4a61d35128fb1b87dc8e2bae538..e8d35aac2efd9e07fc354ed788a117a16a43aec7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp @@ -181,8 +181,7 @@ const ContainerData *getContainerData(ProgramStateRef State, return State->get(Cont); } -const IteratorPosition *getIteratorPosition(ProgramStateRef State, - const SVal &Val) { +const IteratorPosition *getIteratorPosition(ProgramStateRef State, SVal Val) { if (auto Reg = Val.getAsRegion()) { Reg = Reg->getMostDerivedObjectRegion(); return State->get(Reg); @@ -194,7 +193,7 @@ const IteratorPosition *getIteratorPosition(ProgramStateRef State, return nullptr; } -ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val, +ProgramStateRef setIteratorPosition(ProgramStateRef State, SVal Val, const IteratorPosition &Pos) { if (auto Reg = Val.getAsRegion()) { Reg = Reg->getMostDerivedObjectRegion(); @@ -207,8 +206,8 @@ ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val, return nullptr; } -ProgramStateRef createIteratorPosition(ProgramStateRef State, const SVal &Val, - const MemRegion *Cont, const Stmt* S, +ProgramStateRef createIteratorPosition(ProgramStateRef State, SVal Val, + const MemRegion *Cont, const Stmt *S, const LocationContext *LCtx, unsigned blockCount) { auto &StateMgr = State->getStateManager(); @@ -221,9 +220,8 @@ ProgramStateRef createIteratorPosition(ProgramStateRef State, const SVal &Val, IteratorPosition::getPosition(Cont, Sym)); } -ProgramStateRef advancePosition(ProgramStateRef State, const SVal &Iter, - OverloadedOperatorKind Op, - const SVal &Distance) { +ProgramStateRef advancePosition(ProgramStateRef State, SVal Iter, + OverloadedOperatorKind Op, SVal Distance) { const auto *Pos = getIteratorPosition(State, Iter); if (!Pos) return nullptr; diff --git a/clang/lib/StaticAnalyzer/Checkers/Iterator.h b/clang/lib/StaticAnalyzer/Checkers/Iterator.h index 353daf0bed08e74b20a7e04f135483225d264d2e..46de8ea01d77b224c597a74f1000449e7ed6e90f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Iterator.h +++ b/clang/lib/StaticAnalyzer/Checkers/Iterator.h @@ -161,18 +161,15 @@ bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK); bool isRandomIncrOrDecrOperator(BinaryOperatorKind OK); const ContainerData *getContainerData(ProgramStateRef State, const MemRegion *Cont); -const IteratorPosition *getIteratorPosition(ProgramStateRef State, - const SVal &Val); -ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val, +const IteratorPosition *getIteratorPosition(ProgramStateRef State, SVal Val); +ProgramStateRef setIteratorPosition(ProgramStateRef State, SVal Val, const IteratorPosition &Pos); -ProgramStateRef createIteratorPosition(ProgramStateRef State, const SVal &Val, - const MemRegion *Cont, const Stmt* S, +ProgramStateRef createIteratorPosition(ProgramStateRef State, SVal Val, + const MemRegion *Cont, const Stmt *S, const LocationContext *LCtx, unsigned blockCount); -ProgramStateRef advancePosition(ProgramStateRef State, - const SVal &Iter, - OverloadedOperatorKind Op, - const SVal &Distance); +ProgramStateRef advancePosition(ProgramStateRef State, SVal Iter, + OverloadedOperatorKind Op, SVal Distance); ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym, long Scale); bool compare(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2, diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp index 2d51a000ece3c1d2a82890c3596d1536abb06e5a..a95e811c2a418197a6200234bf4679f4a472b635 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp @@ -100,18 +100,17 @@ class IteratorModeling const AdvanceFn *Handler) const; void handleComparison(CheckerContext &C, const Expr *CE, SVal RetVal, - const SVal &LVal, const SVal &RVal, - OverloadedOperatorKind Op) const; + SVal LVal, SVal RVal, OverloadedOperatorKind Op) const; void processComparison(CheckerContext &C, ProgramStateRef State, - SymbolRef Sym1, SymbolRef Sym2, const SVal &RetVal, + SymbolRef Sym1, SymbolRef Sym2, SVal RetVal, OverloadedOperatorKind Op) const; - void handleIncrement(CheckerContext &C, const SVal &RetVal, const SVal &Iter, + void handleIncrement(CheckerContext &C, SVal RetVal, SVal Iter, bool Postfix) const; - void handleDecrement(CheckerContext &C, const SVal &RetVal, const SVal &Iter, + void handleDecrement(CheckerContext &C, SVal RetVal, SVal Iter, bool Postfix) const; void handleRandomIncrOrDecr(CheckerContext &C, const Expr *CE, - OverloadedOperatorKind Op, const SVal &RetVal, - const SVal &Iterator, const SVal &Amount) const; + OverloadedOperatorKind Op, SVal RetVal, + SVal Iterator, SVal Amount) const; void handlePtrIncrOrDecr(CheckerContext &C, const Expr *Iterator, OverloadedOperatorKind OK, SVal Offset) const; void handleAdvance(CheckerContext &C, const Expr *CE, SVal RetVal, SVal Iter, @@ -120,7 +119,7 @@ class IteratorModeling SVal Amount) const; void handleNext(CheckerContext &C, const Expr *CE, SVal RetVal, SVal Iter, SVal Amount) const; - void assignToContainer(CheckerContext &C, const Expr *CE, const SVal &RetVal, + void assignToContainer(CheckerContext &C, const Expr *CE, SVal RetVal, const MemRegion *Cont) const; bool noChangeInAdvance(CheckerContext &C, SVal Iter, const Expr *CE) const; void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, @@ -160,7 +159,7 @@ public: bool isSimpleComparisonOperator(OverloadedOperatorKind OK); bool isSimpleComparisonOperator(BinaryOperatorKind OK); -ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val); +ProgramStateRef removeIteratorPosition(ProgramStateRef State, SVal Val); ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2, bool Equal); bool isBoundThroughLazyCompoundVal(const Environment &Env, @@ -283,7 +282,7 @@ void IteratorModeling::checkPostStmt(const BinaryOperator *BO, // The non-iterator side must have an integral or enumeration type. if (!AmountExpr->getType()->isIntegralOrEnumerationType()) return; - const SVal &AmountVal = IsIterOnLHS ? RVal : LVal; + SVal AmountVal = IsIterOnLHS ? RVal : LVal; handlePtrIncrOrDecr(C, IterExpr, BinaryOperator::getOverloadedOperator(OK), AmountVal); } @@ -388,8 +387,8 @@ IteratorModeling::handleOverloadedOperator(CheckerContext &C, const bool IsIterFirst = FirstType->isStructureOrClassType(); const SVal FirstArg = Call.getArgSVal(0); const SVal SecondArg = Call.getArgSVal(1); - const SVal &Iterator = IsIterFirst ? FirstArg : SecondArg; - const SVal &Amount = IsIterFirst ? SecondArg : FirstArg; + SVal Iterator = IsIterFirst ? FirstArg : SecondArg; + SVal Amount = IsIterFirst ? SecondArg : FirstArg; handleRandomIncrOrDecr(C, OrigExpr, Op, Call.getReturnValue(), Iterator, Amount); @@ -444,14 +443,13 @@ IteratorModeling::handleAdvanceLikeFunction(CheckerContext &C, } void IteratorModeling::handleComparison(CheckerContext &C, const Expr *CE, - SVal RetVal, const SVal &LVal, - const SVal &RVal, - OverloadedOperatorKind Op) const { + SVal RetVal, SVal LVal, SVal RVal, + OverloadedOperatorKind Op) const { // Record the operands and the operator of the comparison for the next // evalAssume, if the result is a symbolic expression. If it is a concrete // value (only one branch is possible), then transfer the state between // the operands according to the operator and the result - auto State = C.getState(); + auto State = C.getState(); const auto *LPos = getIteratorPosition(State, LVal); const auto *RPos = getIteratorPosition(State, RVal); const MemRegion *Cont = nullptr; @@ -504,7 +502,7 @@ void IteratorModeling::handleComparison(CheckerContext &C, const Expr *CE, void IteratorModeling::processComparison(CheckerContext &C, ProgramStateRef State, SymbolRef Sym1, - SymbolRef Sym2, const SVal &RetVal, + SymbolRef Sym2, SVal RetVal, OverloadedOperatorKind Op) const { if (const auto TruthVal = RetVal.getAs()) { if ((State = relateSymbols(State, Sym1, Sym2, @@ -532,8 +530,8 @@ void IteratorModeling::processComparison(CheckerContext &C, } } -void IteratorModeling::handleIncrement(CheckerContext &C, const SVal &RetVal, - const SVal &Iter, bool Postfix) const { +void IteratorModeling::handleIncrement(CheckerContext &C, SVal RetVal, + SVal Iter, bool Postfix) const { // Increment the symbolic expressions which represents the position of the // iterator auto State = C.getState(); @@ -558,8 +556,8 @@ void IteratorModeling::handleIncrement(CheckerContext &C, const SVal &RetVal, C.addTransition(State); } -void IteratorModeling::handleDecrement(CheckerContext &C, const SVal &RetVal, - const SVal &Iter, bool Postfix) const { +void IteratorModeling::handleDecrement(CheckerContext &C, SVal RetVal, + SVal Iter, bool Postfix) const { // Decrement the symbolic expressions which represents the position of the // iterator auto State = C.getState(); @@ -586,9 +584,8 @@ void IteratorModeling::handleDecrement(CheckerContext &C, const SVal &RetVal, void IteratorModeling::handleRandomIncrOrDecr(CheckerContext &C, const Expr *CE, OverloadedOperatorKind Op, - const SVal &RetVal, - const SVal &Iterator, - const SVal &Amount) const { + SVal RetVal, SVal Iterator, + SVal Amount) const { // Increment or decrement the symbolic expressions which represents the // position of the iterator auto State = C.getState(); @@ -684,7 +681,7 @@ void IteratorModeling::handleNext(CheckerContext &C, const Expr *CE, } void IteratorModeling::assignToContainer(CheckerContext &C, const Expr *CE, - const SVal &RetVal, + SVal RetVal, const MemRegion *Cont) const { Cont = Cont->getMostDerivedObjectRegion(); @@ -772,7 +769,7 @@ bool isSimpleComparisonOperator(BinaryOperatorKind OK) { return OK == BO_EQ || OK == BO_NE; } -ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val) { +ProgramStateRef removeIteratorPosition(ProgramStateRef State, SVal Val) { if (auto Reg = Val.getAsRegion()) { Reg = Reg->getMostDerivedObjectRegion(); return State->remove(Reg); diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp index 7740c3d4da1ec2da16c998669ef77bc9e4339786..c8828219dd733d007ed80d330ea961d496d21bfb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp @@ -32,7 +32,8 @@ class IteratorRangeChecker check::PreStmt, check::PreStmt> { - std::unique_ptr OutOfRangeBugType; + const BugType OutOfRangeBugType{this, "Iterator out of range", + "Misuse of STL APIs"}; void verifyDereference(CheckerContext &C, SVal Val) const; void verifyIncrement(CheckerContext &C, SVal Iter) const; @@ -42,12 +43,10 @@ class IteratorRangeChecker void verifyAdvance(CheckerContext &C, SVal LHS, SVal RHS) const; void verifyPrev(CheckerContext &C, SVal LHS, SVal RHS) const; void verifyNext(CheckerContext &C, SVal LHS, SVal RHS) const; - void reportBug(const StringRef &Message, SVal Val, CheckerContext &C, + void reportBug(StringRef Message, SVal Val, CheckerContext &C, ExplodedNode *ErrNode) const; public: - IteratorRangeChecker(); - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const; void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; @@ -67,15 +66,10 @@ public: bool isPastTheEnd(ProgramStateRef State, const IteratorPosition &Pos); bool isAheadOfRange(ProgramStateRef State, const IteratorPosition &Pos); bool isBehindPastTheEnd(ProgramStateRef State, const IteratorPosition &Pos); -bool isZero(ProgramStateRef State, const NonLoc &Val); +bool isZero(ProgramStateRef State, NonLoc Val); } //namespace -IteratorRangeChecker::IteratorRangeChecker() { - OutOfRangeBugType.reset( - new BugType(this, "Iterator out of range", "Misuse of STL APIs")); -} - void IteratorRangeChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { // Check for out of range access @@ -275,10 +269,10 @@ void IteratorRangeChecker::verifyNext(CheckerContext &C, SVal LHS, verifyRandomIncrOrDecr(C, OO_Plus, LHS, RHS); } -void IteratorRangeChecker::reportBug(const StringRef &Message, SVal Val, +void IteratorRangeChecker::reportBug(StringRef Message, SVal Val, CheckerContext &C, ExplodedNode *ErrNode) const { - auto R = std::make_unique(*OutOfRangeBugType, Message, + auto R = std::make_unique(OutOfRangeBugType, Message, ErrNode); const auto *Pos = getIteratorPosition(C.getState(), Val); @@ -295,7 +289,7 @@ bool isLess(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2); bool isGreater(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2); bool isEqual(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2); -bool isZero(ProgramStateRef State, const NonLoc &Val) { +bool isZero(ProgramStateRef State, NonLoc Val) { auto &BVF = State->getBasicVals(); return compare(State, Val, nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0))), diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index b77e9bf09a33204c57dd52275b3f129bb1299a39..de9efe17d220b16d3ccd47600eeaf6e4c0a26ba5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -62,7 +62,8 @@ class NonLocalizedStringChecker check::PostObjCMessage, check::PostStmt> { - mutable std::unique_ptr BT; + const BugType BT{this, "Unlocalizable string", + "Localizability Issue (Apple)"}; // Methods that require a localized string mutable llvm::DenseMap( - *BT, "User-facing text should use localized string macro", ErrNode); + BT, "User-facing text should use localized string macro", ErrNode); if (argumentNumber) { R->addRange(M.getArgExpr(argumentNumber - 1)->getSourceRange()); } else { @@ -817,9 +811,9 @@ void NonLocalizedStringChecker::checkPreObjCMessage(const ObjCMethodCall &msg, // Handle the case where the receiver is an NSString // These special NSString methods draw to the screen - if (!(SelectorName.startswith("drawAtPoint") || - SelectorName.startswith("drawInRect") || - SelectorName.startswith("drawWithRect"))) + if (!(SelectorName.starts_with("drawAtPoint") || + SelectorName.starts_with("drawInRect") || + SelectorName.starts_with("drawWithRect"))) return; SVal svTitle = msg.getReceiverSVal(); diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp index bbf2ddec5762073bdf669ec94ef1ccec3155355e..3e374e6c240e7622c4a7e2bafb0859f3c2da8b0a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp @@ -31,7 +31,7 @@ void MPIBugReporter::reportDoubleNonblocking( RequestRegion->getDescriptiveName() + ". "; auto Report = std::make_unique( - *DoubleNonblockingBugType, ErrorText, ExplNode); + DoubleNonblockingBugType, ErrorText, ExplNode); Report->addRange(MPICallEvent.getSourceRange()); SourceRange Range = RequestRegion->sourceRange(); @@ -53,7 +53,7 @@ void MPIBugReporter::reportMissingWait( std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() + " has no matching wait. "}; - auto Report = std::make_unique(*MissingWaitBugType, + auto Report = std::make_unique(MissingWaitBugType, ErrorText, ExplNode); SourceRange Range = RequestRegion->sourceRange(); @@ -73,7 +73,7 @@ void MPIBugReporter::reportUnmatchedWait( std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() + " has no matching nonblocking call. "}; - auto Report = std::make_unique(*UnmatchedWaitBugType, + auto Report = std::make_unique(UnmatchedWaitBugType, ErrorText, ExplNode); Report->addRange(CE.getSourceRange()); diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h index 9871da026b042809cbdc718f56b6cd8b4804e378..0222a2120b34f34f034484adc0265ab11fbd11bc 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h @@ -17,6 +17,7 @@ #include "MPITypes.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "llvm/ADT/StringRef.h" namespace clang { namespace ento { @@ -24,12 +25,10 @@ namespace mpi { class MPIBugReporter { public: - MPIBugReporter(const CheckerBase &CB) { - UnmatchedWaitBugType.reset(new BugType(&CB, "Unmatched wait", MPIError)); - DoubleNonblockingBugType.reset( - new BugType(&CB, "Double nonblocking", MPIError)); - MissingWaitBugType.reset(new BugType(&CB, "Missing wait", MPIError)); - } + MPIBugReporter(const CheckerBase &CB) + : UnmatchedWaitBugType(&CB, "Unmatched wait", MPIError), + MissingWaitBugType(&CB, "Missing wait", MPIError), + DoubleNonblockingBugType(&CB, "Double nonblocking", MPIError) {} /// Report duplicate request use by nonblocking calls without intermediate /// wait. @@ -68,12 +67,10 @@ public: BugReporter &BReporter) const; private: - const std::string MPIError = "MPI Error"; - - // path-sensitive bug types - std::unique_ptr UnmatchedWaitBugType; - std::unique_ptr MissingWaitBugType; - std::unique_ptr DoubleNonblockingBugType; + const llvm::StringLiteral MPIError = "MPI Error"; + const BugType UnmatchedWaitBugType; + const BugType MissingWaitBugType; + const BugType DoubleNonblockingBugType; /// Bug visitor class to find the node where the request region was previously /// used in order to include it into the BugReport path. diff --git a/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index 771c0a5fbb8d8010050967fdb403ca7ec6fdaf37..12bf12a0b23227acbf2faf2f67d4679ca63c3ef1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -33,7 +33,8 @@ class MacOSKeychainAPIChecker : public Checker, check::DeadSymbols, check::PointerEscape, eval::Assume> { - mutable std::unique_ptr BT; + const BugType BT{this, "Improper use of SecKeychain API", + categories::AppleAPIMisuse}; public: /// AllocationState is a part of the checker specific state together with the @@ -101,12 +102,6 @@ private: /// function. static unsigned getTrackedFunctionIndex(StringRef Name, bool IsAllocator); - inline void initBugType() const { - if (!BT) - BT.reset(new BugType(this, "Improper use of SecKeychain API", - "API Misuse (Apple)")); - } - void generateDeallocatorMismatchReport(const AllocationPair &AP, const Expr *ArgExpr, CheckerContext &C) const; @@ -232,7 +227,6 @@ void MacOSKeychainAPIChecker:: if (!N) return; - initBugType(); SmallString<80> sbuf; llvm::raw_svector_ostream os(sbuf); unsigned int PDeallocIdx = @@ -240,7 +234,7 @@ void MacOSKeychainAPIChecker:: os << "Deallocator doesn't match the allocator: '" << FunctionsToTrack[PDeallocIdx].Name << "' should be used."; - auto Report = std::make_unique(*BT, os.str(), N); + auto Report = std::make_unique(BT, os.str(), N); Report->addVisitor(std::make_unique(AP.first)); Report->addRange(ArgExpr->getSourceRange()); markInteresting(Report.get(), AP); @@ -276,7 +270,6 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, ExplodedNode *N = C.generateNonFatalErrorNode(State); if (!N) return; - initBugType(); SmallString<128> sbuf; llvm::raw_svector_ostream os(sbuf); unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx; @@ -284,8 +277,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, << "the allocator: missing a call to '" << FunctionsToTrack[DIdx].Name << "'."; - auto Report = - std::make_unique(*BT, os.str(), N); + auto Report = std::make_unique(BT, os.str(), N); Report->addVisitor(std::make_unique(V)); Report->addRange(ArgExpr->getSourceRange()); Report->markInteresting(AS->Region); @@ -338,9 +330,8 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, ExplodedNode *N = C.generateNonFatalErrorNode(State); if (!N) return; - initBugType(); auto Report = std::make_unique( - *BT, "Trying to free data which has not been allocated.", N); + BT, "Trying to free data which has not been allocated.", N); Report->addRange(ArgExpr->getSourceRange()); if (AS) Report->markInteresting(AS->Region); @@ -474,7 +465,6 @@ std::unique_ptr MacOSKeychainAPIChecker::generateAllocatedDataNotReleasedReport( const AllocationPair &AP, ExplodedNode *N, CheckerContext &C) const { const ADFunctionInfo &FI = FunctionsToTrack[AP.second->AllocatorIdx]; - initBugType(); SmallString<70> sbuf; llvm::raw_svector_ostream os(sbuf); os << "Allocated data is not released: missing a call to '" @@ -493,7 +483,7 @@ MacOSKeychainAPIChecker::generateAllocatedDataNotReleasedReport( AllocNode->getLocationContext()); auto Report = std::make_unique( - *BT, os.str(), N, LocUsedForUniqueing, + BT, os.str(), N, LocUsedForUniqueing, AllocNode->getLocationContext()->getDecl()); Report->addVisitor(std::make_unique(AP.first)); diff --git a/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp index 04e7f8dec8d77e5a312b49b23eb605eadde5dc67..754b167642961cbec589f10f7efa141b3f24d416 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -18,6 +18,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -31,7 +32,8 @@ using namespace ento; namespace { class MacOSXAPIChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT_dispatchOnce; + const BugType BT_dispatchOnce{this, "Improper use of 'dispatch_once'", + categories::AppleAPIMisuse}; static const ObjCIvarRegion *getParentIvarRegion(const MemRegion *R); @@ -136,12 +138,8 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, if (!N) return; - if (!BT_dispatchOnce) - BT_dispatchOnce.reset(new BugType(this, "Improper use of 'dispatch_once'", - "API Misuse (Apple)")); - auto report = - std::make_unique(*BT_dispatchOnce, os.str(), N); + std::make_unique(BT_dispatchOnce, os.str(), N); report->addRange(CE->getArg(0)->getSourceRange()); C.emitReport(std::move(report)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index c5e4add501886a4d4b654d89d972c210ccba092e..79ab05f2c7866aa2a45e81f2b7b4295f3b01cc4e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -3150,16 +3150,16 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // transferred. Again, though, we can't be sure that the object will use // free() to deallocate the memory, so we can't model it explicitly. StringRef FirstSlot = Msg->getSelector().getNameForSlot(0); - if (FirstSlot.endswith("NoCopy")) + if (FirstSlot.ends_with("NoCopy")) return true; // If the first selector starts with addPointer, insertPointer, // or replacePointer, assume we are dealing with NSPointerArray or similar. // This is similar to C++ containers (vector); we still might want to check // that the pointers get freed by following the container itself. - if (FirstSlot.startswith("addPointer") || - FirstSlot.startswith("insertPointer") || - FirstSlot.startswith("replacePointer") || + if (FirstSlot.starts_with("addPointer") || + FirstSlot.starts_with("insertPointer") || + FirstSlot.starts_with("replacePointer") || FirstSlot.equals("valueWithPointer")) { return true; } @@ -3199,7 +3199,7 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // White list the 'XXXNoCopy' CoreFoundation functions. // We specifically check these before - if (FName.endswith("NoCopy")) { + if (FName.ends_with("NoCopy")) { // Look for the deallocator argument. We know that the memory ownership // is not transferred only if the deallocator argument is // 'kCFAllocatorNull'. diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 2020dc7cc7910ed7b6e64c225ce29286c3c3cf68..82a6228318179a9bb19e6f2b514e276d08d41894 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -30,22 +30,18 @@ namespace { class MismatchedIteratorChecker : public Checker> { - std::unique_ptr MismatchedBugType; - - void verifyMatch(CheckerContext &C, const SVal &Iter, - const MemRegion *Cont) const; - void verifyMatch(CheckerContext &C, const SVal &Iter1, - const SVal &Iter2) const; - void reportBug(const StringRef &Message, const SVal &Val1, - const SVal &Val2, CheckerContext &C, - ExplodedNode *ErrNode) const; - void reportBug(const StringRef &Message, const SVal &Val, - const MemRegion *Reg, CheckerContext &C, + const BugType MismatchedBugType{this, "Iterator(s) mismatched", + "Misuse of STL APIs", + /*SuppressOnSink=*/true}; + + void verifyMatch(CheckerContext &C, SVal Iter, const MemRegion *Cont) const; + void verifyMatch(CheckerContext &C, SVal Iter1, SVal Iter2) const; + void reportBug(StringRef Message, SVal Val1, SVal Val2, CheckerContext &C, ExplodedNode *ErrNode) const; + void reportBug(StringRef Message, SVal Val, const MemRegion *Reg, + CheckerContext &C, ExplodedNode *ErrNode) const; public: - MismatchedIteratorChecker(); - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; @@ -53,12 +49,6 @@ public: } // namespace -MismatchedIteratorChecker::MismatchedIteratorChecker() { - MismatchedBugType.reset( - new BugType(this, "Iterator(s) mismatched", "Misuse of STL APIs", - /*SuppressOnSink=*/true)); -} - void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { // Check for iterator mismatches @@ -202,7 +192,7 @@ void MismatchedIteratorChecker::checkPreStmt(const BinaryOperator *BO, verifyMatch(C, LVal, RVal); } -void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, const SVal &Iter, +void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, SVal Iter, const MemRegion *Cont) const { // Verify match between a container and the container of an iterator Cont = Cont->getMostDerivedObjectRegion(); @@ -238,9 +228,8 @@ void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, const SVal &Iter, } } -void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, - const SVal &Iter1, - const SVal &Iter2) const { +void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, SVal Iter1, + SVal Iter2) const { // Verify match between the containers of two iterators auto State = C.getState(); const auto *Pos1 = getIteratorPosition(State, Iter1); @@ -277,23 +266,21 @@ void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, } } -void MismatchedIteratorChecker::reportBug(const StringRef &Message, - const SVal &Val1, - const SVal &Val2, - CheckerContext &C, +void MismatchedIteratorChecker::reportBug(StringRef Message, SVal Val1, + SVal Val2, CheckerContext &C, ExplodedNode *ErrNode) const { - auto R = std::make_unique(*MismatchedBugType, Message, + auto R = std::make_unique(MismatchedBugType, Message, ErrNode); R->markInteresting(Val1); R->markInteresting(Val2); C.emitReport(std::move(R)); } -void MismatchedIteratorChecker::reportBug(const StringRef &Message, - const SVal &Val, const MemRegion *Reg, +void MismatchedIteratorChecker::reportBug(StringRef Message, SVal Val, + const MemRegion *Reg, CheckerContext &C, ExplodedNode *ErrNode) const { - auto R = std::make_unique(*MismatchedBugType, Message, + auto R = std::make_unique(MismatchedBugType, Message, ErrNode); R->markInteresting(Val); R->markInteresting(Reg); diff --git a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 8fc44e78be6f0732e22e0d908d082e9d22a188a2..2e31c16e457c2e4566cd75f326c3d7bd66740654 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -15,6 +15,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" @@ -31,7 +32,9 @@ class MmapWriteExecChecker : public Checker { static int ProtWrite; static int ProtExec; static int ProtRead; - mutable std::unique_ptr BT; + const BugType BT{this, "W^X check fails, Write Exec prot flags set", + "Security"}; + public: MmapWriteExecChecker() : MmapFn({"mmap"}, 6), MprotectFn({"mprotect"}, 3) {} void checkPreCall(const CallEvent &Call, CheckerContext &C) const; @@ -62,17 +65,16 @@ void MmapWriteExecChecker::checkPreCall(const CallEvent &Call, return; if ((Prot & (ProtWrite | ProtExec)) == (ProtWrite | ProtExec)) { - if (!BT) - BT.reset(new BugType(this, "W^X check fails, Write Exec prot flags set", "Security")); - ExplodedNode *N = C.generateNonFatalErrorNode(); if (!N) return; auto Report = std::make_unique( - *BT, "Both PROT_WRITE and PROT_EXEC flags are set. This can " - "lead to exploitable memory regions, which could be overwritten " - "with malicious code", N); + BT, + "Both PROT_WRITE and PROT_EXEC flags are set. This can " + "lead to exploitable memory regions, which could be overwritten " + "with malicious code", + N); Report->addRange(Call.getArgSourceRange(2)); C.emitReport(std::move(Report)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp index bb01a3b77617260f41d4b10b280ca1cfd02ffc2e..0648084a7d3999f207d73821f5706ddf252b844f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp @@ -31,7 +31,8 @@ using namespace ento; namespace { class NSAutoreleasePoolChecker : public Checker { - mutable std::unique_ptr BT; + const BugType BT{this, "Use -drain instead of -release", + "API Upgrade (Apple)"}; mutable Selector releaseS; public: @@ -57,10 +58,6 @@ void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg, if (msg.getSelector() != releaseS) return; - if (!BT) - BT.reset(new BugType(this, "Use -drain instead of -release", - "API Upgrade (Apple)")); - ExplodedNode *N = C.generateNonFatalErrorNode(); if (!N) { assert(0); @@ -68,7 +65,7 @@ void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg, } auto Report = std::make_unique( - *BT, + BT, "Use -drain instead of -release when using NSAutoreleasePool and " "garbage collection", N); diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index 44b69ef31911c3d12ab3657c2f9bafb14037e1cd..a9002ee7c9661a605c55b7fe8eeea42739fd13c5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -18,6 +18,7 @@ #include "clang/Analysis/AnyCall.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -31,8 +32,9 @@ namespace { class NonNullParamChecker : public Checker> { - mutable std::unique_ptr BTAttrNonNull; - mutable std::unique_ptr BTNullRefArg; + const BugType BTAttrNonNull{ + this, "Argument with 'nonnull' attribute passed null", "API"}; + const BugType BTNullRefArg{this, "Dereference of null pointer"}; public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const; @@ -278,13 +280,6 @@ std::unique_ptr NonNullParamChecker::genReportNullAttrNonNull(const ExplodedNode *ErrorNode, const Expr *ArgE, unsigned IdxOfArg) const { - // Lazily allocate the BugType object if it hasn't already been - // created. Ownership is transferred to the BugReporter object once - // the BugReport is passed to 'EmitWarning'. - if (!BTAttrNonNull) - BTAttrNonNull.reset(new BugType( - this, "Argument with 'nonnull' attribute passed null", "API")); - llvm::SmallString<256> SBuf; llvm::raw_svector_ostream OS(SBuf); OS << "Null pointer passed to " @@ -292,7 +287,7 @@ NonNullParamChecker::genReportNullAttrNonNull(const ExplodedNode *ErrorNode, << " parameter expecting 'nonnull'"; auto R = - std::make_unique(*BTAttrNonNull, SBuf, ErrorNode); + std::make_unique(BTAttrNonNull, SBuf, ErrorNode); if (ArgE) bugreporter::trackExpressionValue(ErrorNode, ArgE, *R); @@ -302,11 +297,8 @@ NonNullParamChecker::genReportNullAttrNonNull(const ExplodedNode *ErrorNode, std::unique_ptr NonNullParamChecker::genReportReferenceToNullPointer( const ExplodedNode *ErrorNode, const Expr *ArgE) const { - if (!BTNullRefArg) - BTNullRefArg.reset(new BugType(this, "Dereference of null pointer")); - auto R = std::make_unique( - *BTNullRefArg, "Forming reference to null pointer", ErrorNode); + BTNullRefArg, "Forming reference to null pointer", ErrorNode); if (ArgE) { const Expr *ArgEDeref = bugreporter::getDerefExpr(ArgE); if (!ArgEDeref) @@ -314,7 +306,6 @@ NonNullParamChecker::genReportReferenceToNullPointer( bugreporter::trackExpressionValue(ErrorNode, ArgEDeref, *R); } return R; - } void ento::registerNonNullParamChecker(CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index 627b51af6bd44af45a43c8e4e89e41cf3af75f14..06f1ad00eaf20ddd6e3fbb9533db127c7ffe2c16 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -890,7 +890,7 @@ void NullabilityChecker::checkPostCall(const CallEvent &Call, // of CG calls. const SourceManager &SM = C.getSourceManager(); StringRef FilePath = SM.getFilename(SM.getSpellingLoc(Decl->getBeginLoc())); - if (llvm::sys::path::filename(FilePath).startswith("CG")) { + if (llvm::sys::path::filename(FilePath).starts_with("CG")) { State = State->set(Region, Nullability::Contradicted); C.addTransition(State); return; @@ -992,7 +992,7 @@ void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M, // In order to reduce the noise in the diagnostics generated by this checker, // some framework and programming style based heuristics are used. These // heuristics are for Cocoa APIs which have NS prefix. - if (Name.startswith("NS")) { + if (Name.starts_with("NS")) { // Developers rely on dynamic invariants such as an item should be available // in a collection, or a collection is not empty often. Those invariants can // not be inferred by any static analysis tool. To not to bother the users diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp index 7906b787cd5346f72ab44278df0e86a1a566403a..552c222a251a636d98b2ead20f2c40d49a47c4be 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp @@ -25,8 +25,10 @@ using namespace ento; namespace { class ObjCAtSyncChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT_null; - mutable std::unique_ptr BT_undef; + const BugType BT_null{this, "Nil value used as mutex for @synchronized() " + "(no synchronization will occur)"}; + const BugType BT_undef{this, "Uninitialized value used as mutex " + "for @synchronized"}; public: void checkPreStmt(const ObjCAtSynchronizedStmt *S, CheckerContext &C) const; @@ -43,11 +45,8 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S, // Uninitialized value used for the mutex? if (isa(V)) { if (ExplodedNode *N = C.generateErrorNode()) { - if (!BT_undef) - BT_undef.reset(new BugType(this, "Uninitialized value used as mutex " - "for @synchronized")); auto report = std::make_unique( - *BT_undef, BT_undef->getDescription(), N); + BT_undef, BT_undef.getDescription(), N); bugreporter::trackExpressionValue(N, Ex, *report); C.emitReport(std::move(report)); } @@ -66,12 +65,8 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S, // Generate an error node. This isn't a sink since // a null mutex just means no synchronization occurs. if (ExplodedNode *N = C.generateNonFatalErrorNode(nullState)) { - if (!BT_null) - BT_null.reset( - new BugType(this, "Nil value used as mutex for @synchronized() " - "(no synchronization will occur)")); auto report = std::make_unique( - *BT_null, BT_null->getDescription(), N); + BT_null, BT_null.getDescription(), N); bugreporter::trackExpressionValue(N, Ex, *report); C.emitReport(std::move(report)); diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp index 0244a7a3ebffb9775f4b64e5eb802edd3b9714d7..28e88245ca95a085d9655eaf58cee75d7abdb343 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -30,12 +30,7 @@ namespace { class ObjCContainersChecker : public Checker< check::PreStmt, check::PostStmt, check::PointerEscape> { - mutable std::unique_ptr BT; - inline void initBugType() const { - if (!BT) - BT.reset(new BugType(this, "CFArray API", - categories::CoreFoundationObjectiveC)); - } + const BugType BT{this, "CFArray API", categories::CoreFoundationObjectiveC}; inline SymbolRef getArraySym(const Expr *E, CheckerContext &C) const { SVal ArrayRef = C.getSVal(E); @@ -140,9 +135,9 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE, ExplodedNode *N = C.generateErrorNode(StOutBound); if (!N) return; - initBugType(); + auto R = std::make_unique( - *BT, "Index is out of bounds", N); + BT, "Index is out of bounds", N); R->addRange(IdxExpr->getSourceRange()); bugreporter::trackExpressionValue(N, IdxExpr, *R, {bugreporter::TrackingKind::Thorough, diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp index 4636fd1605118f776c5afb51f82b26e9287360ba..08ad6877cbe6b6523417caf8f36f8c78f11c1ebf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp @@ -50,7 +50,7 @@ void ObjCPropertyChecker::checkCopyMutable(const ObjCPropertyDecl *D, const std::string &PropTypeName(T->getPointeeType().getCanonicalType() .getUnqualifiedType() .getAsString()); - if (!StringRef(PropTypeName).startswith("NSMutable")) + if (!StringRef(PropTypeName).starts_with("NSMutable")) return; const ObjCImplDecl *ImplD = nullptr; diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp index d88d6a94a30f2803d8a9d5bb302ccd8ff63c29fc..217c46451f80f761c302eef32541defc02a349ef 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -61,13 +61,13 @@ class ObjCSelfInitChecker : public Checker< check::PostObjCMessage, check::PostCall, check::Location, check::Bind > { - mutable std::unique_ptr BT; + const BugType BT{this, "Missing \"self = [(super or self) init...]\"", + categories::CoreFoundationObjectiveC}; void checkForInvalidSelf(const Expr *E, CheckerContext &C, const char *errorStr) const; public: - ObjCSelfInitChecker() {} void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const; void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const; void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; @@ -157,10 +157,7 @@ void ObjCSelfInitChecker::checkForInvalidSelf(const Expr *E, CheckerContext &C, if (!N) return; - if (!BT) - BT.reset(new BugType(this, "Missing \"self = [(super or self) init...]\"", - categories::CoreFoundationObjectiveC)); - C.emitReport(std::make_unique(*BT, errorStr, N)); + C.emitReport(std::make_unique(BT, errorStr, N)); } void ObjCSelfInitChecker::checkPostObjCMessage(const ObjCMethodCall &Msg, diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp index 3547b7bb61a24811f835f07ec91bf698bac5f687..eb40711812e16b2b6c46b572b003fd34f36329ec 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp @@ -26,18 +26,19 @@ namespace { class ObjCSuperDeallocChecker : public Checker { - - mutable IdentifierInfo *IIdealloc, *IINSObject; + mutable IdentifierInfo *IIdealloc = nullptr; + mutable IdentifierInfo *IINSObject = nullptr; mutable Selector SELdealloc; - std::unique_ptr DoubleSuperDeallocBugType; + const BugType DoubleSuperDeallocBugType{ + this, "[super dealloc] should not be called more than once", + categories::CoreFoundationObjectiveC}; void initIdentifierInfoAndSelectors(ASTContext &Ctx) const; bool isSuperDeallocMessage(const ObjCMethodCall &M) const; public: - ObjCSuperDeallocChecker(); void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const; void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const; @@ -188,7 +189,7 @@ void ObjCSuperDeallocChecker::reportUseAfterDealloc(SymbolRef Sym, Desc = "Use of 'self' after it has been deallocated"; // Generate the report. - auto BR = std::make_unique(*DoubleSuperDeallocBugType, + auto BR = std::make_unique(DoubleSuperDeallocBugType, Desc, ErrNode); BR->addRange(S->getSourceRange()); BR->addVisitor(std::make_unique(Sym)); @@ -213,14 +214,6 @@ void ObjCSuperDeallocChecker::diagnoseCallArguments(const CallEvent &CE, } } -ObjCSuperDeallocChecker::ObjCSuperDeallocChecker() - : IIdealloc(nullptr), IINSObject(nullptr) { - - DoubleSuperDeallocBugType.reset( - new BugType(this, "[super dealloc] should not be called more than once", - categories::CoreFoundationObjectiveC)); -} - void ObjCSuperDeallocChecker::initIdentifierInfoAndSelectors(ASTContext &Ctx) const { if (IIdealloc) diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index bd6e1ec3a8fc7ddc3392b09f222e95bf6df3c16e..eee9449f31805c2fe4aa32575c3f57302615ed6a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -32,7 +32,7 @@ using namespace ento; namespace { class PaddingChecker : public Checker> { private: - mutable std::unique_ptr PaddingBug; + const BugType PaddingBug{this, "Excessive Padding", "Performance"}; mutable BugReporter *BR; public: @@ -310,10 +310,6 @@ public: void reportRecord( const RecordDecl *RD, CharUnits BaselinePad, CharUnits OptimalPad, const SmallVector &OptimalFieldsOrder) const { - if (!PaddingBug) - PaddingBug = - std::make_unique(this, "Excessive Padding", "Performance"); - SmallString<100> Buf; llvm::raw_svector_ostream Os(Buf); Os << "Excessive padding in '"; @@ -341,8 +337,7 @@ public: PathDiagnosticLocation CELoc = PathDiagnosticLocation::create(RD, BR->getSourceManager()); - auto Report = - std::make_unique(*PaddingBug, Os.str(), CELoc); + auto Report = std::make_unique(PaddingBug, Os.str(), CELoc); Report->setDeclWithIssue(RD); Report->addRange(RD->getSourceRange()); BR->emitReport(std::move(Report)); diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp index 1d63c0dd01f3d6a10ef4edadc67b85bdfecb7ba3..1141f07428b4cb56cd00e3c2546a21039a11237a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp @@ -56,8 +56,8 @@ class PointerArithChecker bool PointedNeeded = false) const; void initAllocIdentifiers(ASTContext &C) const; - mutable std::unique_ptr BT_pointerArith; - mutable std::unique_ptr BT_polyArray; + const BugType BT_pointerArith{this, "Dangerous pointer arithmetic"}; + const BugType BT_polyArray{this, "Dangerous pointer arithmetic"}; mutable llvm::SmallSet AllocFunctions; public: @@ -168,12 +168,10 @@ void PointerArithChecker::reportPointerArithMisuse(const Expr *E, if (!IsPolymorphic) return; if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - if (!BT_polyArray) - BT_polyArray.reset(new BugType(this, "Dangerous pointer arithmetic")); constexpr llvm::StringLiteral Msg = "Pointer arithmetic on a pointer to base class is dangerous " "because derived and base class may have different size."; - auto R = std::make_unique(*BT_polyArray, Msg, N); + auto R = std::make_unique(BT_polyArray, Msg, N); R->addRange(E->getSourceRange()); R->markInteresting(ArrayRegion); C.emitReport(std::move(R)); @@ -190,12 +188,10 @@ void PointerArithChecker::reportPointerArithMisuse(const Expr *E, return; if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - if (!BT_pointerArith) - BT_pointerArith.reset(new BugType(this, "Dangerous pointer arithmetic")); constexpr llvm::StringLiteral Msg = "Pointer arithmetic on non-array variables relies on memory layout, " "which is dangerous."; - auto R = std::make_unique(*BT_pointerArith, Msg, N); + auto R = std::make_unique(BT_pointerArith, Msg, N); R->addRange(SR); R->markInteresting(Region); C.emitReport(std::move(R)); diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp index 96d38eef3c03a0396e63dcd14f4043d66c2819bc..2438cf30b39b5944a02af256990d3a7907c309e5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -25,7 +25,7 @@ using namespace ento; namespace { class PointerSubChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT; + const BugType BT{this, "Pointer subtraction"}; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; @@ -59,12 +59,10 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B, return; if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - if (!BT) - BT.reset(new BugType(this, "Pointer subtraction")); constexpr llvm::StringLiteral Msg = "Subtraction of two pointers that do not point to the same memory " "chunk may cause incorrect result."; - auto R = std::make_unique(*BT, Msg, N); + auto R = std::make_unique(BT, Msg, N); R->addRange(B->getSourceRange()); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp index 11dca1ff8831d0086cecdfd3c9b4fcb32af36199..09d82ebabd4c97b28063a81a45ae73d659e06b10 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp @@ -26,7 +26,9 @@ using namespace ento; namespace { class ReturnPointerRangeChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT; + // FIXME: This bug correspond to CWE-466. Eventually we should have bug + // types explicitly reference such exploit categories (when applicable). + const BugType BT{this, "Buffer overflow"}; public: void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const; @@ -76,16 +78,12 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS, if (!N) return; - // FIXME: This bug correspond to CWE-466. Eventually we should have bug - // types explicitly reference such exploit categories (when applicable). - if (!BT) - BT.reset(new BugType(this, "Buffer overflow")); constexpr llvm::StringLiteral Msg = "Returned pointer value points outside the original object " "(potential buffer overflow)"; // Generate a report for this bug. - auto Report = std::make_unique(*BT, Msg, N); + auto Report = std::make_unique(BT, Msg, N); Report->addRange(RetE->getSourceRange()); const auto ConcreteElementCount = ElementCount.getAs(); diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp index 78cd0100bea42b4e81132639e7bf11eac0cdef7e..efffbf2ee7559b9ffc3cf72e7d48286aca744acd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp @@ -24,8 +24,8 @@ using namespace ento; namespace { class ReturnUndefChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT_Undef; - mutable std::unique_ptr BT_NullReference; + const BugType BT_Undef{this, "Garbage return value"}; + const BugType BT_NullReference{this, "Returning null reference"}; void emitUndef(CheckerContext &C, const Expr *RetE) const; void checkReference(CheckerContext &C, const Expr *RetE, @@ -77,7 +77,7 @@ void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS, } } -static void emitBug(CheckerContext &C, BugType &BT, StringRef Msg, +static void emitBug(CheckerContext &C, const BugType &BT, StringRef Msg, const Expr *RetE, const Expr *TrackingE = nullptr) { ExplodedNode *N = C.generateErrorNode(); if (!N) @@ -92,9 +92,7 @@ static void emitBug(CheckerContext &C, BugType &BT, StringRef Msg, } void ReturnUndefChecker::emitUndef(CheckerContext &C, const Expr *RetE) const { - if (!BT_Undef) - BT_Undef.reset(new BugType(this, "Garbage return value")); - emitBug(C, *BT_Undef, "Undefined or garbage value returned to caller", RetE); + emitBug(C, BT_Undef, "Undefined or garbage value returned to caller", RetE); } void ReturnUndefChecker::checkReference(CheckerContext &C, const Expr *RetE, @@ -109,10 +107,7 @@ void ReturnUndefChecker::checkReference(CheckerContext &C, const Expr *RetE, } // The return value is known to be null. Emit a bug report. - if (!BT_NullReference) - BT_NullReference.reset(new BugType(this, "Returning null reference")); - - emitBug(C, *BT_NullReference, BT_NullReference->getDescription(), RetE, + emitBug(C, BT_NullReference, BT_NullReference.getDescription(), RetE, bugreporter::getDerefExpr(RetE)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp index 2ac9f65c9793f45450a593aecb25d43460897a04..7cbe271dfbf93a24df30c542b2d66644a591c92e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp @@ -52,10 +52,13 @@ class SimpleStreamChecker : public Checker { - CallDescription OpenFn, CloseFn; + const CallDescription OpenFn{{"fopen"}, 2}; + const CallDescription CloseFn{{"fclose"}, 1}; - std::unique_ptr DoubleCloseBugType; - std::unique_ptr LeakBugType; + const BugType DoubleCloseBugType{this, "Double fclose", + "Unix Stream API Error"}; + const BugType LeakBugType{this, "Resource Leak", "Unix Stream API Error", + /*SuppressOnSink=*/true}; void reportDoubleClose(SymbolRef FileDescSym, const CallEvent &Call, @@ -67,8 +70,6 @@ class SimpleStreamChecker : public Checker( - *DoubleCloseBugType, "Closing a previously closed file stream", ErrNode); + DoubleCloseBugType, "Closing a previously closed file stream", ErrNode); R->addRange(Call.getSourceRange()); R->markInteresting(FileDescSym); C.emitReport(std::move(R)); @@ -205,7 +194,7 @@ void SimpleStreamChecker::reportLeaks(ArrayRef LeakedStreams, // TODO: Identify the leaked file descriptor. for (SymbolRef LeakedStream : LeakedStreams) { auto R = std::make_unique( - *LeakBugType, "Opened file is never closed; potential resource leak", + LeakBugType, "Opened file is never closed; potential resource leak", ErrNode); R->markInteresting(LeakedStream); C.emitReport(std::move(R)); diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index fffcaf7ed18fb7c0af80abeaa414bad75bd26747..6560fd239ce6683dddfafe8023e70c864abe6771 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -823,7 +823,7 @@ class StdLibraryFunctionsChecker using FunctionSummaryMapType = llvm::DenseMap; mutable FunctionSummaryMapType FunctionSummaryMap; - mutable std::unique_ptr BT_InvalidArg; + const BugType BT_InvalidArg{this, "Function call with invalid argument"}; mutable bool SummariesInitialized = false; static SVal getArgSVal(const CallEvent &Call, ArgNo ArgN) { @@ -875,11 +875,7 @@ private: VC->describe(ValueConstraint::Violation, Call, C.getState(), Summary, MsgOs); Msg[0] = toupper(Msg[0]); - if (!BT_InvalidArg) - BT_InvalidArg = std::make_unique( - CheckName, "Function call with invalid argument", - categories::LogicError); - auto R = std::make_unique(*BT_InvalidArg, Msg, N); + auto R = std::make_unique(BT_InvalidArg, Msg, N); for (ArgNo ArgN : VC->getArgsToTrack()) { bugreporter::trackExpressionValue(N, Call.getArgExpr(ArgN), *R); @@ -2244,6 +2240,14 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(0))) .ArgConstraint(NotNull(ArgNo(1)))); + // int fflush(FILE *stream); + addToFunctionSummaryMap( + "fflush", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), + Summary(NoEvalCall) + .Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg) + .Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))}, + ErrnoNEZeroIrrelevant, GenericFailureMsg)); + // long ftell(FILE *stream); // From 'The Open Group Base Specifications Issue 7, 2018 edition': // "The ftell() function shall not change the setting of errno if diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index 925fc90e355431778894e2ee0aa717a4a6e87002..254b36ed03968d57244609ca026ac67840984400 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -266,6 +266,8 @@ private: {&StreamChecker::preFseek, &StreamChecker::evalFseek, 0}}, {{{"ftell"}, 1}, {&StreamChecker::preDefault, &StreamChecker::evalFtell, 0}}, + {{{"fflush"}, 1}, + {&StreamChecker::preFflush, &StreamChecker::evalFflush, 0}}, {{{"rewind"}, 1}, {&StreamChecker::preDefault, &StreamChecker::evalRewind, 0}}, {{{"fgetpos"}, 2}, @@ -360,6 +362,12 @@ private: CheckerContext &C, const StreamErrorState &ErrorKind) const; + void preFflush(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const; + + void evalFflush(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const; + /// Check that the stream (in StreamVal) is not NULL. /// If it can only be NULL a fatal error is emitted and nullptr returned. /// Otherwise the return value is a new state where the stream is constrained @@ -1191,6 +1199,84 @@ void StreamChecker::evalSetFeofFerror(const FnDescription *Desc, C.addTransition(State); } +void StreamChecker::preFflush(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + SVal StreamVal = getStreamArg(Desc, Call); + std::optional Stream = StreamVal.getAs(); + if (!Stream) + return; + + ProgramStateRef StateNotNull, StateNull; + std::tie(StateNotNull, StateNull) = + C.getConstraintManager().assumeDual(State, *Stream); + if (StateNotNull && !StateNull) + ensureStreamOpened(StreamVal, C, StateNotNull); +} + +void StreamChecker::evalFflush(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + SVal StreamVal = getStreamArg(Desc, Call); + std::optional Stream = StreamVal.getAs(); + if (!Stream) + return; + + // Skip if the stream can be both NULL and non-NULL. + ProgramStateRef StateNotNull, StateNull; + std::tie(StateNotNull, StateNull) = + C.getConstraintManager().assumeDual(State, *Stream); + if (StateNotNull && StateNull) + return; + if (StateNotNull && !StateNull) + State = StateNotNull; + else + State = StateNull; + + const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr()); + if (!CE) + return; + + // `fflush` returns EOF on failure, otherwise returns 0. + ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE); + ProgramStateRef StateNotFailed = bindInt(0, State, C, CE); + + // Clear error states if `fflush` returns 0, but retain their EOF flags. + auto ClearErrorInNotFailed = [&StateNotFailed, Desc](SymbolRef Sym, + const StreamState *SS) { + if (SS->ErrorState & ErrorFError) { + StreamErrorState NewES = + (SS->ErrorState & ErrorFEof) ? ErrorFEof : ErrorNone; + StreamState NewSS = StreamState::getOpened(Desc, NewES, false); + StateNotFailed = StateNotFailed->set(Sym, NewSS); + } + }; + + if (StateNotNull && !StateNull) { + // Skip if the input stream's state is unknown, open-failed or closed. + if (SymbolRef StreamSym = StreamVal.getAsSymbol()) { + const StreamState *SS = State->get(StreamSym); + if (SS) { + assert(SS->isOpened() && "Stream is expected to be opened"); + ClearErrorInNotFailed(StreamSym, SS); + } else + return; + } + } else { + // Clear error states for all streams. + const StreamMapTy &Map = StateNotFailed->get(); + for (const auto &I : Map) { + SymbolRef Sym = I.first; + const StreamState &SS = I.second; + if (SS.isOpened()) + ClearErrorInNotFailed(Sym, &SS); + } + } + + C.addTransition(StateNotFailed); + C.addTransition(StateFailed); +} + ProgramStateRef StreamChecker::ensureStreamNonNull(SVal StreamVal, const Expr *StreamE, CheckerContext &C, diff --git a/clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h b/clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h index 557e8a76506e6114fa6955c1b720ab83e8434853..6de33da107a3f94cd5aaab05e38c61307dd8caa1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h +++ b/clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h @@ -52,7 +52,7 @@ removeInformationStoredForDeadInstances(const CallEvent &Call, template void handleConstructorAndAssignment(const CallEvent &Call, CheckerContext &C, - const SVal &ThisSVal) { + SVal ThisSVal) { ProgramStateRef State = Call.getState(); if (!State) diff --git a/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp index 614a2b2e4ec79fac8e104fc3f49c57f324b3f588..acf4e833095b7f03047836bd00d8e62e3fbf21c3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp @@ -23,8 +23,7 @@ using namespace taint; namespace { class TaintTesterChecker : public Checker> { - std::unique_ptr BT = - std::make_unique(this, "Tainted data", "General"); + const BugType BT{this, "Tainted data", "General"}; public: void checkPostStmt(const Expr *E, CheckerContext &C) const; @@ -39,7 +38,7 @@ void TaintTesterChecker::checkPostStmt(const Expr *E, if (isTainted(State, E, C.getLocationContext())) { if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - auto report = std::make_unique(*BT, "tainted", N); + auto report = std::make_unique(BT, "tainted", N); report->addRange(E->getSourceRange()); C.emitReport(std::move(report)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp index 5cdcc1075f444c920bde68622640f1b923cac38a..667b19f8120eaacbed8576dffe42e48e8de1edf7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp @@ -78,7 +78,7 @@ public: class TestAfterDivZeroChecker : public Checker, check::BranchCondition, check::EndFunction> { - mutable std::unique_ptr DivZeroBug; + const BugType DivZeroBug{this, "Division by zero"}; void reportBug(SVal Val, CheckerContext &C) const; public: @@ -165,12 +165,10 @@ bool TestAfterDivZeroChecker::hasDivZeroMap(SVal Var, void TestAfterDivZeroChecker::reportBug(SVal Val, CheckerContext &C) const { if (ExplodedNode *N = C.generateErrorNode(C.getState())) { - if (!DivZeroBug) - DivZeroBug.reset(new BugType(this, "Division by zero")); - auto R = std::make_unique( - *DivZeroBug, "Value being compared against zero has already been used " - "for division", + DivZeroBug, + "Value being compared against zero has already been used " + "for division", N); R->addVisitor(std::make_unique(Val.getAsSymbol(), diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp index db886501a162d0dfe3d9241eaab248645149749d..aa478b69aade1a0e879e9e0263be55cc6c4475ea 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp @@ -27,7 +27,7 @@ using namespace ento; namespace { class UndefBranchChecker : public Checker { - mutable std::unique_ptr BT; + const BugType BT{this, "Branch condition evaluates to a garbage value"}; struct FindUndefExpr { ProgramStateRef St; @@ -64,52 +64,47 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition, // ObjCForCollection is a loop, but has no actual condition. if (isa(Condition)) return; - SVal X = Ctx.getSVal(Condition); - if (X.isUndef()) { - // Generate a sink node, which implicitly marks both outgoing branches as - // infeasible. - ExplodedNode *N = Ctx.generateErrorNode(); - if (N) { - if (!BT) - BT.reset( - new BugType(this, "Branch condition evaluates to a garbage value")); - - // What's going on here: we want to highlight the subexpression of the - // condition that is the most likely source of the "uninitialized - // branch condition." We do a recursive walk of the condition's - // subexpressions and roughly look for the most nested subexpression - // that binds to Undefined. We then highlight that expression's range. - - // Get the predecessor node and check if is a PostStmt with the Stmt - // being the terminator condition. We want to inspect the state - // of that node instead because it will contain main information about - // the subexpressions. - - // Note: any predecessor will do. They should have identical state, - // since all the BlockEdge did was act as an error sink since the value - // had to already be undefined. - assert (!N->pred_empty()); - const Expr *Ex = cast(Condition); - ExplodedNode *PrevN = *N->pred_begin(); - ProgramPoint P = PrevN->getLocation(); - ProgramStateRef St = N->getState(); - - if (std::optional PS = P.getAs()) - if (PS->getStmt() == Ex) - St = PrevN->getState(); - - FindUndefExpr FindIt(St, Ctx.getLocationContext()); - Ex = FindIt.FindExpr(Ex); - - // Emit the bug report. - auto R = std::make_unique( - *BT, BT->getDescription(), N); - bugreporter::trackExpressionValue(N, Ex, *R); - R->addRange(Ex->getSourceRange()); - - Ctx.emitReport(std::move(R)); - } - } + if (!Ctx.getSVal(Condition).isUndef()) + return; + + // Generate a sink node, which implicitly marks both outgoing branches as + // infeasible. + ExplodedNode *N = Ctx.generateErrorNode(); + if (!N) + return; + // What's going on here: we want to highlight the subexpression of the + // condition that is the most likely source of the "uninitialized + // branch condition." We do a recursive walk of the condition's + // subexpressions and roughly look for the most nested subexpression + // that binds to Undefined. We then highlight that expression's range. + + // Get the predecessor node and check if is a PostStmt with the Stmt + // being the terminator condition. We want to inspect the state + // of that node instead because it will contain main information about + // the subexpressions. + + // Note: any predecessor will do. They should have identical state, + // since all the BlockEdge did was act as an error sink since the value + // had to already be undefined. + assert(!N->pred_empty()); + const Expr *Ex = cast(Condition); + ExplodedNode *PrevN = *N->pred_begin(); + ProgramPoint P = PrevN->getLocation(); + ProgramStateRef St = N->getState(); + + if (std::optional PS = P.getAs()) + if (PS->getStmt() == Ex) + St = PrevN->getState(); + + FindUndefExpr FindIt(St, Ctx.getLocationContext()); + Ex = FindIt.FindExpr(Ex); + + // Emit the bug report. + auto R = std::make_unique(BT, BT.getDescription(), N); + bugreporter::trackExpressionValue(N, Ex, *R); + R->addRange(Ex->getSourceRange()); + + Ctx.emitReport(std::move(R)); } void ento::registerUndefBranchChecker(CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp index ecb6ed36ee40cb9c43b17a48e88f01245f50a7be..2839ef0b6d2e610c6d2dc72aacca1c390f9186f7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp @@ -27,7 +27,7 @@ using namespace ento; namespace { class UndefCapturedBlockVarChecker : public Checker< check::PostStmt > { - mutable std::unique_ptr BT; + const BugType BT{this, "uninitialized variable captured by block"}; public: void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; @@ -70,10 +70,6 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE, if (std::optional V = state->getSVal(Var.getOriginalRegion()).getAs()) { if (ExplodedNode *N = C.generateErrorNode()) { - if (!BT) - BT.reset( - new BugType(this, "uninitialized variable captured by block")); - // Generate a bug report. SmallString<128> buf; llvm::raw_svector_ostream os(buf); @@ -81,7 +77,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE, os << "Variable '" << VD->getName() << "' is uninitialized when captured by block"; - auto R = std::make_unique(*BT, os.str(), N); + auto R = std::make_unique(BT, os.str(), N); if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD)) R->addRange(Ex->getSourceRange()); bugreporter::trackStoredValue(*V, VR, *R, diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index d593a6bd74cfea300d2fb0d0a5f44605755693cc..4b845bb3ded23e9db8b9bf8c35d4293e0b076352 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -28,7 +28,7 @@ namespace { class UndefResultChecker : public Checker< check::PostStmt > { - mutable std::unique_ptr BT; + const BugType BT{this, "Result of operation is garbage or undefined"}; public: void checkPostStmt(const BinaryOperator *B, CheckerContext &C) const; @@ -74,10 +74,6 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, if (!N) return; - if (!BT) - BT.reset( - new BugType(this, "Result of operation is garbage or undefined")); - SmallString<256> sbuf; llvm::raw_svector_ostream OS(sbuf); const Expr *Ex = nullptr; @@ -104,7 +100,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, << BinaryOperator::getOpcodeStr(B->getOpcode()) << "' expression is undefined"; } - auto report = std::make_unique(*BT, OS.str(), N); + auto report = std::make_unique(BT, OS.str(), N); if (Ex) { report->addRange(Ex->getSourceRange()); bugreporter::trackExpressionValue(N, Ex, *report); diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp index a6cc8cac8c9925fece32b8d89dfecc6f6d6df59f..baa07fa66764e36bc1fc926e135b52f243e892e0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp @@ -24,7 +24,7 @@ using namespace ento; namespace { class UndefinedArraySubscriptChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT; + const BugType BT{this, "Array subscript is undefined"}; public: void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const; @@ -48,11 +48,8 @@ UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A, ExplodedNode *N = C.generateErrorNode(); if (!N) return; - if (!BT) - BT.reset(new BugType(this, "Array subscript is undefined")); - // Generate a report for this bug. - auto R = std::make_unique(*BT, BT->getDescription(), N); + auto R = std::make_unique(BT, BT.getDescription(), N); R->addRange(A->getIdx()->getSourceRange()); bugreporter::trackExpressionValue(N, A->getIdx(), *R); C.emitReport(std::move(R)); diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp index 49ac94f65dd0c03273c75da9b91bdf5ad41f9f43..ddc6cc9e8202c7c5c46371982ac0599fb5afb79a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp @@ -23,7 +23,7 @@ using namespace ento; namespace { class UndefinedAssignmentChecker : public Checker { - mutable std::unique_ptr BT; + const BugType BT{this, "Assigned value is garbage or undefined"}; public: void checkBind(SVal location, SVal val, const Stmt *S, @@ -49,11 +49,6 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val, if (!N) return; - static const char *const DefaultMsg = - "Assigned value is garbage or undefined"; - if (!BT) - BT.reset(new BugType(this, DefaultMsg)); - // Generate a report for this bug. llvm::SmallString<128> Str; llvm::raw_svector_ostream OS(Str); @@ -105,9 +100,9 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val, } if (OS.str().empty()) - OS << DefaultMsg; + OS << BT.getDescription(); - auto R = std::make_unique(*BT, OS.str(), N); + auto R = std::make_unique(BT, OS.str(), N); if (ex) { R->addRange(ex->getSourceRange()); bugreporter::trackExpressionValue(N, ex, *R); diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h index 2fcdd60863090b5bdcb7295cb55035dbda309d2e..e35778e6480c5b251f496b24dd2b9c164802a128 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h @@ -299,7 +299,7 @@ private: bool isDereferencableUninit(const FieldRegion *FR, FieldChainInfo LocalChain); /// Returns true if the value of a primitive object is uninitialized. - bool isPrimitiveUninit(const SVal &V); + bool isPrimitiveUninit(SVal V); // Note that we don't have a method for arrays -- the elements of an array are // often left uninitialized intentionally even when it is of a C++ record diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp index 3647c49cf3f97d23ffa483332e7106fa5ff3b19c..6e1222fedad3eee974705135390ad445a32dfbbd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -38,15 +38,12 @@ namespace { class UninitializedObjectChecker : public Checker { - std::unique_ptr BT_uninitField; + const BugType BT_uninitField{this, "Uninitialized fields"}; public: // The fields of this struct will be initialized when registering the checker. UninitObjCheckerOptions Opts; - UninitializedObjectChecker() - : BT_uninitField(new BugType(this, "Uninitialized fields")) {} - void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; }; @@ -186,7 +183,7 @@ void UninitializedObjectChecker::checkEndFunction( for (const auto &Pair : UninitFields) { auto Report = std::make_unique( - *BT_uninitField, Pair.second, Node, LocUsedForUniqueing, + BT_uninitField, Pair.second, Node, LocUsedForUniqueing, Node->getLocationContext()->getDecl()); Context.emitReport(std::move(Report)); } @@ -200,7 +197,7 @@ void UninitializedObjectChecker::checkEndFunction( << " at the end of the constructor call"; auto Report = std::make_unique( - *BT_uninitField, WarningOS.str(), Node, LocUsedForUniqueing, + BT_uninitField, WarningOS.str(), Node, LocUsedForUniqueing, Node->getLocationContext()->getDecl()); for (const auto &Pair : UninitFields) { @@ -379,7 +376,7 @@ bool FindUninitializedFields::isUnionUninit(const TypedValueRegion *R) { return false; } -bool FindUninitializedFields::isPrimitiveUninit(const SVal &V) { +bool FindUninitializedFields::isPrimitiveUninit(SVal V) { if (V.isUndef()) return true; diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp index f503b3e88bb35d0de0c5ca5f4fc9fcbdd596705e..b05ce610067cfa1aa81765cd4aaa27cea87d9228 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Basic/TargetInfo.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -39,7 +40,9 @@ enum class OpenVariant { namespace { class UnixAPIMisuseChecker : public Checker< check::PreStmt > { - mutable std::unique_ptr BT_open, BT_pthreadOnce; + const BugType BT_open{this, "Improper use of 'open'", categories::UnixAPI}; + const BugType BT_pthreadOnce{this, "Improper use of 'pthread_once'", + categories::UnixAPI}; mutable std::optional Val_O_CREAT; public: @@ -64,7 +67,9 @@ public: void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; private: - mutable std::unique_ptr BT_mallocZero; + const BugType BT_mallocZero{ + this, "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)", + categories::UnixAPI}; void CheckCallocZero(CheckerContext &C, const CallExpr *CE) const; void CheckMallocZero(CheckerContext &C, const CallExpr *CE) const; @@ -87,14 +92,6 @@ private: } //end anonymous namespace -static void LazyInitialize(const CheckerBase *Checker, - std::unique_ptr &BT, - const char *name) { - if (BT) - return; - BT.reset(new BugType(Checker, name, categories::UnixAPI)); -} - //===----------------------------------------------------------------------===// // "open" (man 2 open) //===----------------------------------------------------------------------===/ @@ -132,9 +129,7 @@ void UnixAPIMisuseChecker::ReportOpenBug(CheckerContext &C, if (!N) return; - LazyInitialize(this, BT_open, "Improper use of 'open'"); - - auto Report = std::make_unique(*BT_open, Msg, N); + auto Report = std::make_unique(BT_open, Msg, N); Report->addRange(SR); C.emitReport(std::move(Report)); } @@ -301,10 +296,8 @@ void UnixAPIMisuseChecker::CheckPthreadOnce(CheckerContext &C, if (isa(R) && isa(R->getMemorySpace())) os << " Perhaps you intended to declare the variable as 'static'?"; - LazyInitialize(this, BT_pthreadOnce, "Improper use of 'pthread_once'"); - auto report = - std::make_unique(*BT_pthreadOnce, os.str(), N); + std::make_unique(BT_pthreadOnce, os.str(), N); report->addRange(CE->getArg(0)->getSourceRange()); C.emitReport(std::move(report)); } @@ -341,14 +334,11 @@ bool UnixAPIPortabilityChecker::ReportZeroByteAllocation( if (!N) return false; - LazyInitialize(this, BT_mallocZero, - "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)"); - SmallString<256> S; llvm::raw_svector_ostream os(S); os << "Call to '" << fn_name << "' has an allocation size of 0 bytes"; auto report = - std::make_unique(*BT_mallocZero, os.str(), N); + std::make_unique(BT_mallocZero, os.str(), N); report->addRange(arg->getSourceRange()); bugreporter::trackExpressionValue(N, arg, *report); diff --git a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp index 1d03d1656b3cb1428efe4ae945a73019bc44d512..d76fe49918690c0b7de8fe48cfbceab54a0eae01 100644 --- a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp @@ -34,8 +34,10 @@ namespace { class VLASizeChecker : public Checker, check::PreStmt> { - mutable std::unique_ptr BT; - mutable std::unique_ptr TaintBT; + const BugType BT{this, "Dangerous variable-length array (VLA) declaration"}; + const BugType TaintBT{this, + "Dangerous variable-length array (VLA) declaration", + categories::TaintedData}; enum VLASize_Kind { VLA_Garbage, VLA_Zero, VLA_Negative, VLA_Overflow }; /// Check a VLA for validity. @@ -213,17 +215,12 @@ void VLASizeChecker::reportTaintBug(const Expr *SizeE, ProgramStateRef State, if (!N) return; - if (!TaintBT) - TaintBT.reset( - new BugType(this, "Dangerous variable-length array (VLA) declaration", - categories::TaintedData)); - SmallString<256> buf; llvm::raw_svector_ostream os(buf); os << "Declared variable-length array (VLA) "; os << "has tainted size"; - auto report = std::make_unique(*TaintBT, os.str(), N); + auto report = std::make_unique(TaintBT, os.str(), N); report->addRange(SizeE->getSourceRange()); bugreporter::trackExpressionValue(N, SizeE, *report); // The vla size may be a complex expression where multiple memory locations @@ -240,11 +237,6 @@ void VLASizeChecker::reportBug(VLASize_Kind Kind, const Expr *SizeE, if (!N) return; - if (!BT) - BT.reset(new BugType(this, - "Dangerous variable-length array (VLA) declaration", - categories::LogicError)); - SmallString<256> buf; llvm::raw_svector_ostream os(buf); os << "Declared variable-length array (VLA) "; @@ -263,7 +255,7 @@ void VLASizeChecker::reportBug(VLASize_Kind Kind, const Expr *SizeE, break; } - auto report = std::make_unique(*BT, os.str(), N); + auto report = std::make_unique(BT, os.str(), N); report->addRange(SizeE->getSourceRange()); bugreporter::trackExpressionValue(N, SizeE, *report); C.emitReport(std::move(report)); diff --git a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp index 8a1e02748c9b2b83e967109faaf59eddfa21576a..cb73ac68edd1ea58d5a8d25218b0fe3d9a342dd5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp @@ -44,7 +44,7 @@ namespace { class VforkChecker : public Checker> { - mutable std::unique_ptr BT; + const BugType BT{this, "Dangerous construct in a vforked process"}; mutable llvm::SmallSet VforkAllowlist; mutable const IdentifierInfo *II_vfork = nullptr; @@ -123,9 +123,6 @@ bool VforkChecker::isCallExplicitelyAllowed(const IdentifierInfo *II, void VforkChecker::reportBug(const char *What, CheckerContext &C, const char *Details) const { if (ExplodedNode *N = C.generateErrorNode(C.getState())) { - if (!BT) - BT.reset(new BugType(this, "Dangerous construct in a vforked process")); - SmallString<256> buf; llvm::raw_svector_ostream os(buf); @@ -134,7 +131,7 @@ void VforkChecker::reportBug(const char *What, CheckerContext &C, if (Details) os << "; " << Details; - auto Report = std::make_unique(*BT, os.str(), N); + auto Report = std::make_unique(BT, os.str(), N); // TODO: mark vfork call in BugReportVisitor C.emitReport(std::move(Report)); } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 9532254e3c459681bef893d7f4905fd5040d778a..f3e0a5f9f314aded8b40e30a8a919d1ab6d400dd 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -12,12 +12,15 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ParentMap.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" @@ -2139,15 +2142,14 @@ PathSensitiveBugReport::PathSensitiveBugReport( "checkers to emit warnings, because checkers should depend on " "*modeling*, not *diagnostics*."); - assert( - (bt.getCheckerName().startswith("debug") || - !isHidden(ErrorNode->getState() - ->getAnalysisManager() - .getCheckerManager() - ->getCheckerRegistryData(), - bt.getCheckerName())) && - "Hidden checkers musn't emit diagnostics as they are by definition " - "non-user facing!"); + assert((bt.getCheckerName().starts_with("debug") || + !isHidden(ErrorNode->getState() + ->getAnalysisManager() + .getCheckerManager() + ->getCheckerRegistryData(), + bt.getCheckerName())) && + "Hidden checkers musn't emit diagnostics as they are by definition " + "non-user facing!"); } void PathSensitiveBugReport::addVisitor( @@ -2425,6 +2427,12 @@ PathSensitiveBugReport::getLocation() const { } if (S) { + // Attributed statements usually have corrupted begin locations, + // it's OK to ignore attributes for our purposes and deal with + // the actual annotated statement. + if (const auto *AS = dyn_cast(S)) + S = AS->getSubStmt(); + // For member expressions, return the location of the '.' or '->'. if (const auto *ME = dyn_cast(S)) return PathDiagnosticLocation::createMemberLoc(ME, SM); @@ -2897,6 +2905,10 @@ void BugReporter::emitReport(std::unique_ptr R) { if (!ValidSourceLoc) return; + // If the user asked to suppress this report, we should skip it. + if (UserSuppressions.isSuppressed(*R)) + return; + // Compute the bug report's hash to determine its equivalence class. llvm::FoldingSetNodeID ID; R->Profile(ID); @@ -3064,8 +3076,7 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { // See whether we need to silence the checker/package. for (const std::string &CheckerOrPackage : getAnalyzerOptions().SilencedCheckersAndPackages) { - if (report->getBugType().getCheckerName().startswith( - CheckerOrPackage)) + if (report->getBugType().getCheckerName().starts_with(CheckerOrPackage)) return; } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 4a9d130c240aec307dce9fc4189a257b9f3645df..2f9965036b9ef91fe9181c50fad3c88269f5e739 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -3372,7 +3372,7 @@ void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor( FullSourceLoc Loc = BR.getLocation().asLocation(); while (Loc.isMacroID()) { Loc = Loc.getSpellingLoc(); - if (SM.getFilename(Loc).endswith("sys/queue.h")) { + if (SM.getFilename(Loc).ends_with("sys/queue.h")) { BR.markInvalid(getTag(), nullptr); return; } diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5991e47a5388752c4a6318fd89d6e1610d8c3df --- /dev/null +++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp @@ -0,0 +1,169 @@ +//===- BugSuppression.cpp - Suppression interface -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" + +using namespace clang; +using namespace ento; + +namespace { + +using Ranges = llvm::SmallVectorImpl; + +inline bool hasSuppression(const Decl *D) { + // FIXME: Implement diagnostic identifier arguments + // (checker names, "hashtags"). + if (const auto *Suppression = D->getAttr()) + return !Suppression->isGSL() && + (Suppression->diagnosticIdentifiers().empty()); + return false; +} +inline bool hasSuppression(const AttributedStmt *S) { + // FIXME: Implement diagnostic identifier arguments + // (checker names, "hashtags"). + return llvm::any_of(S->getAttrs(), [](const Attr *A) { + const auto *Suppression = dyn_cast(A); + return Suppression && !Suppression->isGSL() && + (Suppression->diagnosticIdentifiers().empty()); + }); +} + +template inline SourceRange getRange(const NodeType *Node) { + return Node->getSourceRange(); +} +template <> inline SourceRange getRange(const AttributedStmt *S) { + // Begin location for attributed statement node seems to be ALWAYS invalid. + // + // It is unlikely that we ever report any warnings on suppression + // attribute itself, but even if we do, we wouldn't want that warning + // to be suppressed by that same attribute. + // + // Long story short, we can use inner statement and it's not going to break + // anything. + return getRange(S->getSubStmt()); +} + +inline bool isLessOrEqual(SourceLocation LHS, SourceLocation RHS, + const SourceManager &SM) { + // SourceManager::isBeforeInTranslationUnit tests for strict + // inequality, when we need a non-strict comparison (bug + // can be reported directly on the annotated note). + // For this reason, we use the following equivalence: + // + // A <= B <==> !(B < A) + // + return !SM.isBeforeInTranslationUnit(RHS, LHS); +} + +inline bool fullyContains(SourceRange Larger, SourceRange Smaller, + const SourceManager &SM) { + // Essentially this means: + // + // Larger.fullyContains(Smaller) + // + // However, that method has a very trivial implementation and couldn't + // compare regular locations and locations from macro expansions. + // We could've converted everything into regular locations as a solution, + // but the following solution seems to be the most bulletproof. + return isLessOrEqual(Larger.getBegin(), Smaller.getBegin(), SM) && + isLessOrEqual(Smaller.getEnd(), Larger.getEnd(), SM); +} + +class CacheInitializer : public RecursiveASTVisitor { +public: + static void initialize(const Decl *D, Ranges &ToInit) { + CacheInitializer(ToInit).TraverseDecl(const_cast(D)); + } + + bool VisitVarDecl(VarDecl *VD) { + // Bug location could be somewhere in the init value of + // a freshly declared variable. Even though it looks like the + // user applied attribute to a statement, it will apply to a + // variable declaration, and this is where we check for it. + return VisitAttributedNode(VD); + } + + bool VisitAttributedStmt(AttributedStmt *AS) { + // When we apply attributes to statements, it actually creates + // a wrapper statement that only contains attributes and the wrapped + // statement. + return VisitAttributedNode(AS); + } + +private: + template bool VisitAttributedNode(NodeType *Node) { + if (hasSuppression(Node)) { + // TODO: In the future, when we come up with good stable IDs for checkers + // we can return a list of kinds to ignore, or all if no arguments + // were provided. + addRange(getRange(Node)); + } + // We should keep traversing AST. + return true; + } + + void addRange(SourceRange R) { + if (R.isValid()) { + Result.push_back(R); + } + } + + CacheInitializer(Ranges &R) : Result(R) {} + Ranges &Result; +}; + +} // end anonymous namespace + +// TODO: Introduce stable IDs for checkers and check for those here +// to be more specific. Attribute without arguments should still +// be considered as "suppress all". +// It is already much finer granularity than what we have now +// (i.e. removing the whole function from the analysis). +bool BugSuppression::isSuppressed(const BugReport &R) { + PathDiagnosticLocation Location = R.getLocation(); + PathDiagnosticLocation UniqueingLocation = R.getUniqueingLocation(); + const Decl *DeclWithIssue = R.getDeclWithIssue(); + + return isSuppressed(Location, DeclWithIssue, {}) || + isSuppressed(UniqueingLocation, DeclWithIssue, {}); +} + +bool BugSuppression::isSuppressed(const PathDiagnosticLocation &Location, + const Decl *DeclWithIssue, + DiagnosticIdentifierList Hashtags) { + if (!Location.isValid() || DeclWithIssue == nullptr) + return false; + + // While some warnings are attached to AST nodes (mostly path-sensitive + // checks), others are simply associated with a plain source location + // or range. Figuring out the node based on locations can be tricky, + // so instead, we traverse the whole body of the declaration and gather + // information on ALL suppressions. After that we can simply check if + // any of those suppressions affect the warning in question. + // + // Traversing AST of a function is not a heavy operation, but for + // large functions with a lot of bugs it can make a dent in performance. + // In order to avoid this scenario, we cache traversal results. + auto InsertionResult = CachedSuppressionLocations.insert( + std::make_pair(DeclWithIssue, CachedRanges{})); + Ranges &SuppressionRanges = InsertionResult.first->second; + if (InsertionResult.second) { + // We haven't checked this declaration for suppressions yet! + CacheInitializer::initialize(DeclWithIssue, SuppressionRanges); + } + + SourceRange BugRange = Location.asRange(); + const SourceManager &SM = Location.getManager(); + + return llvm::any_of(SuppressionRanges, + [BugRange, &SM](SourceRange Suppression) { + return fullyContains(Suppression, BugRange, SM); + }); +} diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt index 3df93374dada753bf1edaf821f532bace6c63de2..8672876c0608d0de06d81785081e309ea2765c2a 100644 --- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_library(clangStaticAnalyzerCore BlockCounter.cpp BugReporter.cpp BugReporterVisitors.cpp + BugSuppression.cpp CallDescription.cpp CallEvent.cpp Checker.cpp diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index d004c12bf2c1e8b36d372badf6041ea6c78a5e68..0ac1d91b79beb5ac2d00838a45b2097f15b8fe32 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -659,17 +659,17 @@ bool AnyFunctionCall::argumentsMayEscape() const { // - CoreFoundation functions that end with "NoCopy" can free a passed-in // buffer even if it is const. - if (FName.endswith("NoCopy")) + if (FName.ends_with("NoCopy")) return true; // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can // be deallocated by NSMapRemove. - if (FName.startswith("NS") && FName.contains("Insert")) + if (FName.starts_with("NS") && FName.contains("Insert")) return true; // - Many CF containers allow objects to escape through custom // allocators/deallocators upon container construction. (PR12101) - if (FName.startswith("CF") || FName.startswith("CG")) { + if (FName.starts_with("CF") || FName.starts_with("CG")) { return StrInStrNoCase(FName, "InsertValue") != StringRef::npos || StrInStrNoCase(FName, "AddValue") != StringRef::npos || StrInStrNoCase(FName, "SetValue") != StringRef::npos || diff --git a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp index c25165cce1287650a9b64f0e35b37edc231f948c..d6d4cec9dd3d4d01dd5ab2ffb9fbbeab337e4ddb 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp @@ -105,10 +105,11 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, if (FName.equals(Name)) return true; - if (FName.startswith("__inline") && FName.contains(Name)) + if (FName.starts_with("__inline") && FName.contains(Name)) return true; - if (FName.startswith("__") && FName.endswith("_chk") && FName.contains(Name)) + if (FName.starts_with("__") && FName.ends_with("_chk") && + FName.contains(Name)) return true; return false; diff --git a/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp b/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp index 1b3e8b11549dd9d5b029649e6b94adcd52d8b971..b9c6278991f43f6a8092390a7e2b83106fb9bd89 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp @@ -82,7 +82,7 @@ static constexpr char PackageSeparator = '.'; static bool isInPackage(const CheckerInfo &Checker, StringRef PackageName) { // Does the checker's full name have the package as a prefix? - if (!Checker.FullName.startswith(PackageName)) + if (!Checker.FullName.starts_with(PackageName)) return false; // Is the package actually just the name of a specific checker? @@ -158,7 +158,7 @@ void CheckerRegistryData::printCheckerWithDescList( continue; } - if (Checker.FullName.startswith("alpha")) { + if (Checker.FullName.starts_with("alpha")) { if (AnOpts.ShowCheckerHelpAlpha) Print(Out, Checker, ("(Enable only for development!) " + Checker.Desc).str()); @@ -228,7 +228,7 @@ void CheckerRegistryData::printCheckerOptionList(const AnalyzerOptions &AnOpts, } if (Option.DevelopmentStatus == "alpha" || - Entry.first.startswith("alpha")) { + Entry.first.starts_with("alpha")) { if (AnOpts.ShowCheckerOptionAlphaList) Print(Out, FullOption, llvm::Twine("(Enable only for development!) " + Desc).str()); diff --git a/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp b/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp index e9cc080caf5f85147ac3b11e7c1c0ed2b696cfec..66fab523c864728bd9e56692b3c36a6381051f62 100644 --- a/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp +++ b/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp @@ -13,6 +13,7 @@ namespace clang { namespace ento { namespace categories { +const char *const AppleAPIMisuse = "API Misuse (Apple)"; const char *const CoreFoundationObjectiveC = "Core Foundation/Objective-C"; const char *const LogicError = "Logic error"; const char *const MemoryRefCount = diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index 0102f743c9110dc2c6dc3135d4bd51a4672f359d..4f989ed59bee38c73ec209d98e389bc11e062d80 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -193,7 +193,7 @@ EnvironmentManager::removeDeadBindings(Environment Env, // Iterate over the block-expr bindings. for (Environment::iterator I = Env.begin(), End = Env.end(); I != End; ++I) { const EnvironmentEntry &BlkExpr = I.getKey(); - const SVal &X = I.getData(); + SVal X = I.getData(); const Expr *E = dyn_cast(BlkExpr.getStmt()); if (!E) diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index c773cef30d5ec3db1796fe80ee0438853615e8e8..da9a1a1a4d1f6945713311ddd02d2e7ea47f879f 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2016,7 +2016,7 @@ std::optional RegionStoreManager::getBindingForDerivedDefaultValue( const TypedValueRegion *R, QualType Ty) { if (const std::optional &D = B.getDefaultBinding(superR)) { - const SVal &val = *D; + SVal val = *D; if (SymbolRef parentSym = val.getAsSymbol()) return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); @@ -2331,7 +2331,7 @@ bool RegionStoreManager::includedInBindings(Store store, const ClusterBindings &Cluster = RI.getData(); for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end(); CI != CE; ++CI) { - const SVal &D = CI.getData(); + SVal D = CI.getData(); if (const MemRegion *R = D.getAsRegion()) if (R->getBaseRegion() == region) return true; @@ -2500,7 +2500,7 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B, if (VI == VE) break; - const NonLoc &Idx = svalBuilder.makeArrayIndex(i); + NonLoc Idx = svalBuilder.makeArrayIndex(i); const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx); if (ElementTy->isStructureOrClassType()) diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 142acab7cd081d4ed884d7aaa3623a319eec6443..b6ef40595e3c97a5e218516f84d5d325263a7540 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -308,7 +308,7 @@ public: bool VisitFunctionDecl(FunctionDecl *FD) { IdentifierInfo *II = FD->getIdentifier(); - if (II && II->getName().startswith("__inline")) + if (II && II->getName().starts_with("__inline")) return true; // We skip function template definitions, as their semantics is diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index f0d3f43c414c6e715b47045dcf7261adc235a8bf..317df90a7781e243f178897019173bfc9a8c1983 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -310,8 +310,8 @@ template void CheckerRegistry::resolveDependencies() { "Failed to find the dependency of a checker!"); // We do allow diagnostics from unit test/example dependency checkers. - assert((DependencyIt->FullName.startswith("test") || - DependencyIt->FullName.startswith("example") || IsWeak || + assert((DependencyIt->FullName.starts_with("test") || + DependencyIt->FullName.starts_with("example") || IsWeak || DependencyIt->IsHidden) && "Strong dependencies are modeling checkers, and as such " "non-user facing! Mark them hidden in Checkers.td!"); diff --git a/clang/lib/Support/RISCVVIntrinsicUtils.cpp b/clang/lib/Support/RISCVVIntrinsicUtils.cpp index a04694e628de4041be05fdaf2121db9409f13a69..2de977a3dc720bd632b4644863d7e88d60fa5a2d 100644 --- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp +++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp @@ -203,7 +203,7 @@ void RVVType::initBuiltinStr() { } break; case ScalarTypeKind::BFloat: - BuiltinStr += "b"; + BuiltinStr += "y"; break; default: llvm_unreachable("ScalarType is invalid!"); @@ -464,7 +464,7 @@ PrototypeDescriptor::parsePrototypeDescriptor( PrototypeDescriptorStr = PrototypeDescriptorStr.drop_back(); // Compute the vector type transformers, it can only appear one time. - if (PrototypeDescriptorStr.startswith("(")) { + if (PrototypeDescriptorStr.starts_with("(")) { assert(VTM == VectorTypeModifier::NoModifier && "VectorTypeModifier should only have one modifier"); size_t Idx = PrototypeDescriptorStr.find(')'); @@ -1217,7 +1217,7 @@ raw_ostream &operator<<(raw_ostream &OS, const RVVIntrinsicRecord &Record) { OS << (int)Record.PrototypeLength << ","; OS << (int)Record.SuffixLength << ","; OS << (int)Record.OverloadedSuffixSize << ","; - OS << (int)Record.RequiredExtensions << ","; + OS << Record.RequiredExtensions << ","; OS << (int)Record.TypeRangeMask << ","; OS << (int)Record.Log2LMULMask << ","; OS << (int)Record.NF << ","; diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp index 52e57976ac09117422d21e999dcaa83bc1c188a0..356b4bd5a1b85cbef27c0cc3e8436cf19afd9e22 100644 --- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp +++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp @@ -371,7 +371,7 @@ SyntaxTree::Impl::getRelativeName(const NamedDecl *ND, // Strip the qualifier, if Val refers to something in the current scope. // But leave one leading ':' in place, so that we know that this is a // relative path. - if (!ContextPrefix.empty() && StringRef(Val).startswith(ContextPrefix)) + if (!ContextPrefix.empty() && StringRef(Val).starts_with(ContextPrefix)) Val = Val.substr(ContextPrefix.size() + 1); return Val; } diff --git a/clang/lib/Tooling/ArgumentsAdjusters.cpp b/clang/lib/Tooling/ArgumentsAdjusters.cpp index e40df625737841e67c2e06a855cf43c335626f09..df4c74205b0874d7ed5e40cb54f6e633974c1c79 100644 --- a/clang/lib/Tooling/ArgumentsAdjusters.cpp +++ b/clang/lib/Tooling/ArgumentsAdjusters.cpp @@ -45,12 +45,12 @@ ArgumentsAdjuster getClangSyntaxOnlyAdjuster() { StringRef Arg = Args[i]; // Skip output commands. if (llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) { - return Arg.startswith(OutputCommand); + return Arg.starts_with(OutputCommand); })) continue; - if (!Arg.startswith("-fcolor-diagnostics") && - !Arg.startswith("-fdiagnostics-color")) + if (!Arg.starts_with("-fcolor-diagnostics") && + !Arg.starts_with("-fdiagnostics-color")) AdjustedArgs.push_back(Args[i]); // If we strip a color option, make sure we strip any preceeding `-Xclang` // option as well. @@ -73,7 +73,7 @@ ArgumentsAdjuster getClangStripOutputAdjuster() { CommandLineArguments AdjustedArgs; for (size_t i = 0, e = Args.size(); i < e; ++i) { StringRef Arg = Args[i]; - if (!Arg.startswith("-o")) + if (!Arg.starts_with("-o")) AdjustedArgs.push_back(Args[i]); if (Arg == "-o") { @@ -102,11 +102,11 @@ ArgumentsAdjuster getClangStripDependencyFileAdjuster() { // When not using the cl driver mode, dependency file generation options // begin with -M. These include -MM, -MF, -MG, -MP, -MT, -MQ, -MD, and // -MMD. - if (!UsingClDriver && Arg.startswith("-M")) + if (!UsingClDriver && Arg.starts_with("-M")) continue; // Under MSVC's cl driver mode, dependency file generation is controlled // using /showIncludes - if (Arg.startswith("/showIncludes") || Arg.startswith("-showIncludes")) + if (Arg.starts_with("/showIncludes") || Arg.starts_with("-showIncludes")) continue; AdjustedArgs.push_back(Args[i]); @@ -159,7 +159,7 @@ ArgumentsAdjuster getStripPluginsAdjuster() { // -Xclang if (I + 4 < E && Args[I] == "-Xclang" && (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" || - llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") || + llvm::StringRef(Args[I + 1]).starts_with("-plugin-arg-") || Args[I + 1] == "-add-plugin") && Args[I + 2] == "-Xclang") { I += 3; diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp index fdf6015508d94ba3686413a925797c65c30a2975..87ad8f25a1ab4ed0094e4e98352cd06e112d6806 100644 --- a/clang/lib/Tooling/CompilationDatabase.cpp +++ b/clang/lib/Tooling/CompilationDatabase.cpp @@ -204,7 +204,7 @@ public: // which don't support these options. struct FilterUnusedFlags { bool operator() (StringRef S) { - return (S == "-no-integrated-as") || S.startswith("-Wa,"); + return (S == "-no-integrated-as") || S.starts_with("-Wa,"); } }; diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index 3e53c8fc57408754544d6da182bfa3d3ae95e342..6f71650a3982c08448e2aaea676257e99a619314 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -290,7 +290,7 @@ DependencyScanningWorkerFilesystem::status(const Twine &Path) { SmallString<256> OwnedFilename; StringRef Filename = Path.toStringRef(OwnedFilename); - if (Filename.endswith(".pcm")) + if (Filename.ends_with(".pcm")) return getUnderlyingFS().status(Path); llvm::ErrorOr Result = getOrCreateFileSystemEntry(Filename); @@ -350,7 +350,7 @@ DependencyScanningWorkerFilesystem::openFileForRead(const Twine &Path) { SmallString<256> OwnedFilename; StringRef Filename = Path.toStringRef(OwnedFilename); - if (Filename.endswith(".pcm")) + if (Filename.ends_with(".pcm")) return getUnderlyingFS().openFileForRead(Path); llvm::ErrorOr Result = getOrCreateFileSystemEntry(Filename); diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index f65da413bb87c35d46ceb76d5daf1d085d7d27d7..bfaa897851041db83e56818b357246df76b8441e 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -119,6 +119,8 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) { // units. CI.getFrontendOpts().Inputs.clear(); CI.getFrontendOpts().OutputFile.clear(); + // LLVM options are not going to affect the AST + CI.getFrontendOpts().LLVMArgs.clear(); // TODO: Figure out better way to set options to their default value. CI.getCodeGenOpts().MainFileName.clear(); @@ -530,7 +532,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { // this file in the proper directory and relies on the rest of Clang to // handle it like normal. With explicitly built modules we don't need // to play VFS tricks, so replace it with the correct module map. - if (StringRef(IFI.Filename).endswith("__inferred_module.map")) { + if (StringRef(IFI.Filename).ends_with("__inferred_module.map")) { MDC.addFileDep(MD, ModuleMap->getName()); return; } @@ -548,7 +550,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { if (!(IFI.TopLevel && IFI.ModuleMap)) return; if (StringRef(IFI.FilenameAsRequested) - .endswith("__inferred_module.map")) + .ends_with("__inferred_module.map")) return; MD.ModuleMapFileDeps.emplace_back(IFI.FilenameAsRequested); }); diff --git a/clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp b/clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp index 0b3c4de08ab8593e8206c43ae4272d85335693f4..52b634e2e1af8a5a283e40e51b5d7bb7ba270d43 100644 --- a/clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp +++ b/clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp @@ -21,7 +21,7 @@ bool isIf(llvm::StringRef Line) { if (!Line.consume_front("#")) return false; Line = Line.ltrim(); - return Line.startswith("if"); + return Line.starts_with("if"); } // Is Line an #error directive mentioning includes? @@ -30,7 +30,7 @@ bool isErrorAboutInclude(llvm::StringRef Line) { if (!Line.consume_front("#")) return false; Line = Line.ltrim(); - if (!Line.startswith("error")) + if (!Line.starts_with("error")) return false; return Line.contains_insensitive( "includ"); // Matches "include" or "including". @@ -54,7 +54,7 @@ bool isImportLine(llvm::StringRef Line) { if (!Line.consume_front("#")) return false; Line = Line.ltrim(); - return Line.startswith("import"); + return Line.starts_with("import"); } llvm::StringRef getFileContents(FileEntryRef FE, const SourceManager &SM) { diff --git a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp index 15a2024c4788870d83cbae1a9e15d7d7ad381e1b..d275222ac6b5874bf2db91eb4f93244154b11274 100644 --- a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp +++ b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp @@ -196,10 +196,10 @@ IncludeCategoryManager::IncludeCategoryManager(const IncludeStyle &Style, ? llvm::Regex::NoFlags : llvm::Regex::IgnoreCase); } - IsMainFile = FileName.endswith(".c") || FileName.endswith(".cc") || - FileName.endswith(".cpp") || FileName.endswith(".c++") || - FileName.endswith(".cxx") || FileName.endswith(".m") || - FileName.endswith(".mm"); + IsMainFile = FileName.ends_with(".c") || FileName.ends_with(".cc") || + FileName.ends_with(".cpp") || FileName.ends_with(".c++") || + FileName.ends_with(".cxx") || FileName.ends_with(".m") || + FileName.ends_with(".mm"); if (!Style.IncludeIsMainSourceRegex.empty()) { llvm::Regex MainFileRegex(Style.IncludeIsMainSourceRegex); IsMainFile |= MainFileRegex.match(FileName); @@ -234,7 +234,7 @@ int IncludeCategoryManager::getSortIncludePriority(StringRef IncludeName, return Ret; } bool IncludeCategoryManager::isMainHeader(StringRef IncludeName) const { - if (!IncludeName.startswith("\"")) + if (!IncludeName.starts_with("\"")) return false; IncludeName = @@ -357,8 +357,8 @@ HeaderIncludes::insert(llvm::StringRef IncludeName, bool IsAngled, if (It != ExistingIncludes.end()) { for (const auto &Inc : It->second) if (Inc.Directive == Directive && - ((IsAngled && StringRef(Inc.Name).startswith("<")) || - (!IsAngled && StringRef(Inc.Name).startswith("\"")))) + ((IsAngled && StringRef(Inc.Name).starts_with("<")) || + (!IsAngled && StringRef(Inc.Name).starts_with("\"")))) return std::nullopt; } std::string Quoted = @@ -400,8 +400,8 @@ tooling::Replacements HeaderIncludes::remove(llvm::StringRef IncludeName, if (Iter == ExistingIncludes.end()) return Result; for (const auto &Inc : Iter->second) { - if ((IsAngled && StringRef(Inc.Name).startswith("\"")) || - (!IsAngled && StringRef(Inc.Name).startswith("<"))) + if ((IsAngled && StringRef(Inc.Name).starts_with("\"")) || + (!IsAngled && StringRef(Inc.Name).starts_with("<"))) continue; llvm::Error Err = Result.add(tooling::Replacement( FileName, Inc.R.getOffset(), Inc.R.getLength(), "")); diff --git a/clang/lib/Tooling/Refactoring/AtomicChange.cpp b/clang/lib/Tooling/Refactoring/AtomicChange.cpp index 7237393f00e57e239e025d164fd317a3ee3f2a2b..3d5ae2fed014c441aeba7271c9f15967089d2009 100644 --- a/clang/lib/Tooling/Refactoring/AtomicChange.cpp +++ b/clang/lib/Tooling/Refactoring/AtomicChange.cpp @@ -150,7 +150,7 @@ createReplacementsForHeaders(llvm::StringRef FilePath, llvm::StringRef Code, for (const auto &Change : Changes) { for (llvm::StringRef Header : Change.getInsertedHeaders()) { std::string EscapedHeader = - Header.startswith("<") || Header.startswith("\"") + Header.starts_with("<") || Header.starts_with("\"") ? Header.str() : ("\"" + Header + "\"").str(); std::string ReplacementText = "#include " + EscapedHeader; diff --git a/clang/lib/Tooling/Refactoring/Lookup.cpp b/clang/lib/Tooling/Refactoring/Lookup.cpp index 9468d4d032a7945ba3d653240522408627459ce0..757fba0404e62dc0384c56a6e2b019e8bb8fd24e 100644 --- a/clang/lib/Tooling/Refactoring/Lookup.cpp +++ b/clang/lib/Tooling/Refactoring/Lookup.cpp @@ -98,8 +98,8 @@ static StringRef getBestNamespaceSubstr(const DeclContext *DeclA, // from NewName if it has an identical prefix. std::string NS = "::" + cast(DeclA)->getQualifiedNameAsString() + "::"; - if (NewName.startswith(NS)) - return NewName.substr(NS.size()); + if (NewName.consume_front(NS)) + return NewName; // No match yet. Strip of a namespace from the end of the chain and try // again. This allows to get optimal qualifications even if the old and new @@ -128,9 +128,9 @@ static std::string disambiguateSpellingInScope(StringRef Spelling, StringRef QName, const DeclContext &UseContext, SourceLocation UseLoc) { - assert(QName.startswith("::")); - assert(QName.endswith(Spelling)); - if (Spelling.startswith("::")) + assert(QName.starts_with("::")); + assert(QName.ends_with(Spelling)); + if (Spelling.starts_with("::")) return std::string(Spelling); auto UnspelledSpecifier = QName.drop_back(Spelling.size()); @@ -146,7 +146,7 @@ static std::string disambiguateSpellingInScope(StringRef Spelling, UseLoc = SM.getSpellingLoc(UseLoc); auto IsAmbiguousSpelling = [&](const llvm::StringRef CurSpelling) { - if (CurSpelling.startswith("::")) + if (CurSpelling.starts_with("::")) return false; // Lookup the first component of Spelling in all enclosing namespaces // and check if there is any existing symbols with the same name but in @@ -160,7 +160,7 @@ static std::string disambiguateSpellingInScope(StringRef Spelling, // ambiguous. For example, a reference in a header file should not be // affected by a potentially ambiguous name in some file that includes // the header. - if (!TrimmedQName.startswith(Res->getQualifiedNameAsString()) && + if (!TrimmedQName.starts_with(Res->getQualifiedNameAsString()) && SM.isBeforeInTranslationUnit( SM.getSpellingLoc(Res->getLocation()), UseLoc)) return true; @@ -187,7 +187,7 @@ std::string tooling::replaceNestedName(const NestedNameSpecifier *Use, const DeclContext *UseContext, const NamedDecl *FromDecl, StringRef ReplacementString) { - assert(ReplacementString.startswith("::") && + assert(ReplacementString.starts_with("::") && "Expected fully-qualified name!"); // We can do a raw name replacement when we are not inside the namespace for diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp index 9cdeeec0574b4d0749d38983c81a9c6613ccfa9a..c18f9290471fe4262db39a126b7bd8d9a8dc643f 100644 --- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp @@ -562,8 +562,8 @@ createRenameAtomicChanges(llvm::ArrayRef USRs, ReplacedName = tooling::replaceNestedName( RenameInfo.Specifier, RenameInfo.Begin, RenameInfo.Context->getDeclContext(), RenameInfo.FromDecl, - NewName.startswith("::") ? NewName.str() - : ("::" + NewName).str()); + NewName.starts_with("::") ? NewName.str() + : ("::" + NewName).str()); } else { // This fixes the case where type `T` is a parameter inside a function // type (e.g. `std::function`) and the DeclContext of `T` @@ -578,13 +578,13 @@ createRenameAtomicChanges(llvm::ArrayRef USRs, SM, TranslationUnitDecl->getASTContext().getLangOpts()); // Add the leading "::" back if the name written in the code contains // it. - if (ActualName.startswith("::") && !NewName.startswith("::")) { + if (ActualName.starts_with("::") && !NewName.starts_with("::")) { ReplacedName = "::" + NewName.str(); } } } // If the NewName contains leading "::", add it back. - if (NewName.startswith("::") && NewName.substr(2) == ReplacedName) + if (NewName.starts_with("::") && NewName.substr(2) == ReplacedName) ReplacedName = NewName.str(); } Replace(RenameInfo.Begin, RenameInfo.End, ReplacedName); diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index e292fa724d2bb712122e69042d8e09ee55d08edf..d192c7f4293968290bf0014dfb1f3ee76f69d147 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -255,9 +255,7 @@ llvm::Expected getAbsolutePath(llvm::vfs::FileSystem &FS, StringRef File) { StringRef RelativePath(File); // FIXME: Should '.\\' be accepted on Win32? - if (RelativePath.startswith("./")) { - RelativePath = RelativePath.substr(strlen("./")); - } + RelativePath.consume_front("./"); SmallString<1024> AbsolutePath = RelativePath; if (auto EC = FS.makeAbsolute(AbsolutePath)) @@ -294,9 +292,9 @@ void addTargetAndModeForProgramName(std::vector &CommandLine, for (auto Token = ++CommandLine.begin(); Token != CommandLine.end(); ++Token) { StringRef TokenRef(*Token); - ShouldAddTarget = ShouldAddTarget && !TokenRef.startswith(TargetOPT) && + ShouldAddTarget = ShouldAddTarget && !TokenRef.starts_with(TargetOPT) && !TokenRef.equals(TargetOPTLegacy); - ShouldAddMode = ShouldAddMode && !TokenRef.startswith(DriverModeOPT); + ShouldAddMode = ShouldAddMode && !TokenRef.starts_with(DriverModeOPT); } if (ShouldAddMode) { CommandLine.insert(++CommandLine.begin(), TargetMode.DriverMode); @@ -507,7 +505,7 @@ static void injectResourceDir(CommandLineArguments &Args, const char *Argv0, void *MainAddr) { // Allow users to override the resource dir. for (StringRef Arg : Args) - if (Arg.startswith("-resource-dir")) + if (Arg.starts_with("-resource-dir")) return; // If there's no override in place add our resource dir. diff --git a/clang/lib/Tooling/Transformer/SourceCode.cpp b/clang/lib/Tooling/Transformer/SourceCode.cpp index 30009537b5923ced0ea42ff86d91492fae7799a9..6aae834b0db563ea336dfdfabf431c28b8e3ac94 100644 --- a/clang/lib/Tooling/Transformer/SourceCode.cpp +++ b/clang/lib/Tooling/Transformer/SourceCode.cpp @@ -425,7 +425,7 @@ CharSourceRange tooling::getAssociatedRange(const Decl &Decl, for (llvm::StringRef Prefix : {"[[", "__attribute__(("}) { // Handle whitespace between attribute prefix and attribute value. - if (BeforeAttrStripped.endswith(Prefix)) { + if (BeforeAttrStripped.ends_with(Prefix)) { // Move start to start position of prefix, which is // length(BeforeAttr) - length(BeforeAttrStripped) + length(Prefix) // positions to the left. diff --git a/clang/test/ARCMT/Inputs/module.map b/clang/test/ARCMT/Inputs/module.modulemap similarity index 100% rename from clang/test/ARCMT/Inputs/module.map rename to clang/test/ARCMT/Inputs/module.modulemap diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66490e973988bb5409bf55f029e44a9b8823578a --- /dev/null +++ b/clang/test/AST/Interp/complex.cpp @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s +// RUN: %clang_cc1 -verify=ref %s + +// expected-no-diagnostics +// ref-no-diagnostics + +constexpr _Complex double z1 = {1.0, 2.0}; +static_assert(__real(z1) == 1.0, ""); +static_assert(__imag(z1) == 2.0, ""); + +constexpr double setter() { + _Complex float d = {1.0, 2.0}; + + __imag(d) = 4.0; + return __imag(d); +} +static_assert(setter() == 4, ""); + +constexpr _Complex double getter() { + return {1.0, 3.0}; +} +constexpr _Complex double D = getter(); +static_assert(__real(D) == 1.0, ""); +static_assert(__imag(D) == 3.0, ""); + + +constexpr _Complex int I1 = {1, 2}; +static_assert(__real(I1) == 1, ""); +static_assert(__imag(I1) == 2, ""); + + +constexpr _Complex double D1 = {}; +static_assert(__real(D1) == 0, ""); +static_assert(__imag(D1) == 0, ""); + +constexpr _Complex int I2 = {}; +static_assert(__real(I2) == 0, ""); +static_assert(__imag(I2) == 0, ""); + + +/// Standalone complex expressions. +static_assert(__real((_Complex float){1.0, 3.0}) == 1.0, ""); + + +#if 0 +/// FIXME: This should work in the new interpreter. +constexpr _Complex double D2 = {12}; +static_assert(__real(D2) == 12, ""); +static_assert(__imag(D2) == 12, ""); + +constexpr _Complex int I3 = {15}; +static_assert(__real(I3) == 15, ""); +static_assert(__imag(I3) == 15, ""); +#endif + +/// FIXME: This should work in the new interpreter as well. +// constexpr _Complex _BitInt(8) A = 0;// = {4}; + +namespace CastToBool { + constexpr _Complex int F = {0, 1}; + static_assert(F, ""); + constexpr _Complex int F2 = {1, 0}; + static_assert(F2, ""); + constexpr _Complex int F3 = {0, 0}; + static_assert(!F3, ""); + + constexpr _Complex unsigned char F4 = {0, 1}; + static_assert(F4, ""); + constexpr _Complex unsigned char F5 = {1, 0}; + static_assert(F5, ""); + constexpr _Complex unsigned char F6 = {0, 0}; + static_assert(!F6, ""); + + constexpr _Complex float F7 = {0, 1}; + static_assert(F7, ""); + constexpr _Complex float F8 = {1, 0}; + static_assert(F8, ""); + constexpr _Complex double F9 = {0, 0}; + static_assert(!F9, ""); +} + +namespace BinOps { +namespace Add { + constexpr _Complex float A = { 13.0, 2.0 }; + constexpr _Complex float B = { 2.0, 1.0 }; + constexpr _Complex float C = A + B; + static_assert(__real(C) == 15.0, ""); + static_assert(__imag(C) == 3.0, ""); + + constexpr _Complex float D = B + A; + static_assert(__real(D) == 15.0, ""); + static_assert(__imag(D) == 3.0, ""); + + constexpr _Complex unsigned int I1 = { 5, 10 }; + constexpr _Complex unsigned int I2 = { 40, 2 }; + constexpr _Complex unsigned int I3 = I1 + I2; + static_assert(__real(I3) == 45, ""); + static_assert(__imag(I3) == 12, ""); +} + +namespace Sub { + constexpr _Complex float A = { 13.0, 2.0 }; + constexpr _Complex float B = { 2.0, 1.0 }; + constexpr _Complex float C = A - B; + static_assert(__real(C) == 11.0, ""); + static_assert(__imag(C) == 1.0, ""); + + constexpr _Complex float D = B - A; + static_assert(__real(D) == -11.0, ""); + static_assert(__imag(D) == -1.0, ""); + + constexpr _Complex unsigned int I1 = { 5, 10 }; + constexpr _Complex unsigned int I2 = { 40, 2 }; + constexpr _Complex unsigned int I3 = I1 - I2; + static_assert(__real(I3) == -35, ""); + static_assert(__imag(I3) == 8, ""); + + using Bobble = _Complex float; + constexpr _Complex float A_ = { 13.0, 2.0 }; + constexpr Bobble B_ = { 2.0, 1.0 }; + constexpr _Complex float D_ = A_ - B_; + static_assert(__real(D_) == 11.0, ""); + static_assert(__imag(D_) == 1.0, ""); +} + +} diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index ab562e70606b6721c95d66cbdb9ad7f7afd27a47..179a195098b1327879b16d80791e876be90d3c43 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -267,6 +267,17 @@ namespace InvalidCall { // ref-error {{must be initialized by a constant expression}} \ // ref-note {{in call to 'SS()'}} + + /// This should not emit a diagnostic. + constexpr int f(); + constexpr int a() { + return f(); + } + constexpr int f() { + return 5; + } + static_assert(a() == 5, ""); + } namespace CallWithArgs { diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index 7089bd8bfc9d983db384f23a32e74d0d86f1e1c9..409a969a0d4ccee7b5f6971ddc50f75c4a11e89c 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -61,6 +61,7 @@ void clearerr(FILE *stream); int feof(FILE *stream); int ferror(FILE *stream); int fileno(FILE *stream); +int fflush(FILE *stream); size_t strlen(const char *); diff --git a/clang/test/Analysis/stream-errno.c b/clang/test/Analysis/stream-errno.c index bf0a61db2424f9ba7ec86dda3409ae7e65bd1550..f44ee6070708b2671dd9a29c87bf9f1c474a4854 100644 --- a/clang/test/Analysis/stream-errno.c +++ b/clang/test/Analysis/stream-errno.c @@ -222,3 +222,29 @@ void check_fileno(void) { } if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}} } + +void check_fflush_opened_file(void) { + FILE *F = tmpfile(); + if (!F) + return; + int N = fflush(F); + if (N == EOF) { + clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} + if (errno) {} // no-warning + } else { + clang_analyzer_eval(N == 0); // expected-warning{{TRUE}} + if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}} + } + fclose(F); +} + +void check_fflush_all(void) { + int N = fflush(NULL); + if (N == 0) { + if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}} + } else { + clang_analyzer_eval(N == EOF); // expected-warning{{TRUE}} + clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} + if (errno) {} // no-warning + } +} diff --git a/clang/test/Analysis/stream-error.c b/clang/test/Analysis/stream-error.c index c8332bcbfa8ca72f8678d47d0226e2d1d99cec44..37e1e54dfc89d5895faad78e39d47aa75e5daed8 100644 --- a/clang/test/Analysis/stream-error.c +++ b/clang/test/Analysis/stream-error.c @@ -299,6 +299,73 @@ void error_fseek_0(void) { fclose(F); } +void error_fflush_after_fclose(void) { + FILE *F = tmpfile(); + int Ret; + fflush(NULL); // no-warning + if (!F) + return; + if ((Ret = fflush(F)) != 0) + clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} + fclose(F); + fflush(F); // expected-warning {{Stream might be already closed}} +} + +void error_fflush_on_open_failed_stream(void) { + FILE *F = tmpfile(); + if (!F) { + fflush(F); // no-warning + return; + } + fclose(F); +} + +void error_fflush_on_unknown_stream(FILE *F) { + fflush(F); // no-warning + fclose(F); // no-warning +} + +void error_fflush_on_non_null_stream_clear_error_states(void) { + FILE *F0 = tmpfile(), *F1 = tmpfile(); + // `fflush` clears a non-EOF stream's error state. + if (F0) { + StreamTesterChecker_make_ferror_stream(F0); + if (fflush(F0) == 0) { // no-warning + clang_analyzer_eval(ferror(F0)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F0)); // expected-warning {{FALSE}} + } + fclose(F0); + } + // `fflush` clears an EOF stream's error state. + if (F1) { + StreamTesterChecker_make_feof_stream(F1); + if (fflush(F1) == 0) { // no-warning + clang_analyzer_eval(ferror(F1)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F1)); // expected-warning {{TRUE}} + } + fclose(F1); + } +} + +void error_fflush_on_null_stream_clear_error_states(void) { + FILE *F0 = tmpfile(), *F1 = tmpfile(); + // `fflush` clears all stream's error states, while retains their EOF states. + if (F0 && F1) { + StreamTesterChecker_make_ferror_stream(F0); + StreamTesterChecker_make_feof_stream(F1); + if (fflush(NULL) == 0) { // no-warning + clang_analyzer_eval(ferror(F0)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F0)); // expected-warning {{FALSE}} + clang_analyzer_eval(ferror(F1)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F1)); // expected-warning {{TRUE}} + } + } + if (F0) + fclose(F0); + if (F1) + fclose(F1); +} + void error_indeterminate(void) { FILE *F = fopen("file", "r+"); if (!F) diff --git a/clang/test/Analysis/string.cpp b/clang/test/Analysis/string.cpp index f86416da6ee2370b567957da0c3cea773bdc327b..1be6c21466cc0318a67eb435af2a23897074ee7e 100644 --- a/clang/test/Analysis/string.cpp +++ b/clang/test/Analysis/string.cpp @@ -1,6 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s - -// expected-no-diagnostics +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s // Test functions that are called "memcpy" but aren't the memcpy // we're looking for. Unfortunately, this test cannot be put into @@ -9,6 +7,11 @@ typedef __typeof(sizeof(int)) size_t; void *memcpy(void *, const void *, size_t); +int sprintf(char *str, const char *format, ...); +int snprintf(char *str, size_t size, const char *format, ...); + +void clang_analyzer_warnIfReached(); + struct S { static S s1, s2; @@ -26,3 +29,19 @@ void *memcpy(void *, const S &, size_t); void test_out_of_class_weird_memcpy() { memcpy(&S::s1, S::s2, 1); // no-crash } + +template +void log(const char* fmt, const Args&... args) { + char buf[100] = {}; + auto f = snprintf; + auto g = sprintf; + int n = 0; + n += f(buf, 99, fmt, args...); // no-crash: The CalleeDecl is a VarDecl, but it's okay. + n += g(buf, fmt, args...); // no-crash: Same. + (void)n; + clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} +} + +void test_gh_74269_no_crash() { + log("%d", 1); +} diff --git a/clang/test/Analysis/suppression-attr-doc.cpp b/clang/test/Analysis/suppression-attr-doc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1208842799ed9a1d635019b63518d6e354cf6221 --- /dev/null +++ b/clang/test/Analysis/suppression-attr-doc.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix \ +// RUN: -analyzer-disable-checker=core.uninitialized \ +// RUN: -verify %s + +// NOTE: These tests correspond to examples provided in documentation +// of [[clang::suppress]]. If you break them intentionally, it's likely that +// you need to update the documentation! + +typedef __typeof(sizeof(int)) size_t; +void *malloc(size_t); + +int foo_initial() { + int *x = nullptr; + return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +} + +int foo1() { + int *x = nullptr; + [[clang::suppress]] + return *x; // null pointer dereference warning suppressed here +} + +int foo2() { + [[clang::suppress]] { + int *x = nullptr; + return *x; // null pointer dereference warning suppressed here + } +} + +int bar_initial(bool coin_flip) { + int *result = (int *)malloc(sizeof(int)); + if (coin_flip) + return 1; // There's no warning here YET, but it will show up if the other one is suppressed. + + return *result; // expected-warning{{Potential leak of memory pointed to by 'result'}} +} + +int bar1(bool coin_flip) { + __attribute__((suppress)) + int *result = (int *)malloc(sizeof(int)); + if (coin_flip) + return 1; // warning about this leak path is suppressed + + return *result; // warning about this leak path also suppressed +} + +int bar2(bool coin_flip) { + int *result = (int *)malloc(sizeof(int)); + if (coin_flip) + return 1; // expected-warning{{Potential leak of memory pointed to by 'result'}} + + __attribute__((suppress)) + return *result; // leak warning is suppressed only on this path +} diff --git a/clang/test/Analysis/suppression-attr.m b/clang/test/Analysis/suppression-attr.m new file mode 100644 index 0000000000000000000000000000000000000000..8ba8dda722721b2b1257fc7302d5cb18795b5eb4 --- /dev/null +++ b/clang/test/Analysis/suppression-attr.m @@ -0,0 +1,271 @@ +// RUN: %clang_analyze_cc1 -fblocks \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=osx.cocoa.MissingSuperCall \ +// RUN: -analyzer-checker=osx.cocoa.NSError \ +// RUN: -analyzer-checker=osx.ObjCProperty \ +// RUN: -analyzer-checker=osx.cocoa.RetainCount \ +// RUN: -analyzer-checker=unix.Malloc \ +// RUN: -analyzer-checker=alpha.core.CastToStruct \ +// RUN: -Wno-unused-value -Wno-objc-root-class -verify %s + +#define SUPPRESS __attribute__((suppress)) +#define SUPPRESS_SPECIFIC(...) __attribute__((suppress(__VA_ARGS__))) + +@protocol NSObject +- (id)retain; +- (oneway void)release; +@end +@interface NSObject { +} +- (id)init; ++ (id)alloc; +@end +typedef int NSInteger; +typedef char BOOL; +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@class NSDictionary; +@interface NSError : NSObject { +} ++ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; +@end + +@interface NSMutableString : NSObject +@end + +typedef __typeof__(sizeof(int)) size_t; +void *malloc(size_t); +void free(void *); + +void dereference_1() { + int *x = 0; + *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +} + +void dereference_suppression_1() { + int *x = 0; + SUPPRESS { *x; } // no-warning +} + +void dereference_2() { + int *x = 0; + if (*x) { // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} + } +} + +void dereference_suppression_2() { + int *x = 0; + SUPPRESS if (*x) { // no-warning + } +} + +void dereference_suppression_2a() { + int *x = 0; + // FIXME: Implement suppressing individual checkers. + SUPPRESS_SPECIFIC("core.NullDereference") if (*x) { // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} + } +} + +void dereference_suppression_2b() { + int *x = 0; + // This is not a MallocChecker issue so it shouldn't be suppressed. (Though the attribute + // doesn't really understand any of those arguments yet.) + SUPPRESS_SPECIFIC("unix.Malloc") if (*x) { // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} + } +} + +void dereference_3(int cond) { + int *x = 0; + if (cond) { + (*x)++; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} + } +} + +void dereference_suppression_3(int cond) { + int *x = 0; + SUPPRESS if (cond) { + (*x)++; // no-warning + } +} + +void dereference_4() { + int *x = 0; + int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +} + +void dereference_suppression_4() { + int *x = 0; + SUPPRESS int y = *x; // no-warning +} + +void dereference_5() { + int *x = 0; + int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} + int z = *x; // no-warning (duplicate) +} + +void dereference_suppression_5_1() { + int *x = 0; + SUPPRESS int y = *x; // no-warning + int z = *x; // no-warning (duplicate) +} + +void dereference_suppression_5_2() { + int *x = 0; + int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} + SUPPRESS int z = *x; // no-warning +} + +void do_deref(int *y) { + *y = 1; // expected-warning{{Dereference of null pointer (loaded from variable 'y')}} +} + +void dereference_interprocedural() { + int *x = 0; + do_deref(x); +} + +void do_deref_suppressed(int *y) { + SUPPRESS *y = 1; // no-warning +} + +void dereference_interprocedural_suppressed() { + int *x = 0; + do_deref_suppressed(x); +} + +int malloc_leak_1() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; + return *x; // expected-warning{{Potential leak of memory pointed to by 'x'}} +} + +int malloc_leak_suppression_1_1() { + SUPPRESS int *x = (int *)malloc(sizeof(int)); + *x = 42; + return *x; +} + +int malloc_leak_suppression_1_2() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; + SUPPRESS return *x; +} + +void malloc_leak_2() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; +} // expected-warning{{Potential leak of memory pointed to by 'x'}} + +void malloc_leak_suppression_2_1() { + SUPPRESS int *x = (int *)malloc(sizeof(int)); + *x = 42; +} + +// TODO: reassess when we decide what to do with declaration annotations +void malloc_leak_suppression_2_2() /* SUPPRESS */ { + int *x = (int *)malloc(sizeof(int)); + *x = 42; +} // expected-warning{{Potential leak of memory pointed to by 'x'}} + +// TODO: reassess when we decide what to do with declaration annotations +/* SUPPRESS */ void malloc_leak_suppression_2_3() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; +} // expected-warning{{Potential leak of memory pointed to by 'x'}} + +void malloc_leak_suppression_2_4(int cond) { + int *x = (int *)malloc(sizeof(int)); + *x = 42; + SUPPRESS; + // FIXME: The warning should be suppressed but dead symbol elimination + // happens too late. +} // expected-warning{{Potential leak of memory pointed to by 'x'}} + +void retain_release_leak_1() { + [[NSMutableString alloc] init]; // expected-warning{{Potential leak of an object of type 'NSMutableString *'}} +} + +void retain_release_leak_suppression_1() { + SUPPRESS { [[NSMutableString alloc] init]; } +} + +void retain_release_leak_2(int cond) { + id obj = [[NSMutableString alloc] init]; // expected-warning{{Potential leak of an object stored into 'obj'}} + if (cond) { + [obj release]; + } +} + +void retain_release_leak__suppression_2(int cond) { + SUPPRESS id obj = [[NSMutableString alloc] init]; + if (cond) { + [obj release]; + } +} + +@interface UIResponder : NSObject { +} +- (char)resignFirstResponder; +@end + +@interface Test : UIResponder { +} +@property(copy) NSMutableString *mutableStr; +// expected-warning@-1 {{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}} +@end +@implementation Test + +- (BOOL)resignFirstResponder { + return 0; +} // expected-warning {{The 'resignFirstResponder' instance method in UIResponder subclass 'Test' is missing a [super resignFirstResponder] call}} + +- (void)methodWhichMayFail:(NSError **)error { + // expected-warning@-1 {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}} +} +@end + +@interface TestSuppress : UIResponder { +} +// TODO: reassess when we decide what to do with declaration annotations +@property(copy) /* SUPPRESS */ NSMutableString *mutableStr; +// expected-warning@-1 {{Property of mutable type 'NSMutableString' has 'copy' attribute; an immutable object will be stored instead}} +@end +@implementation TestSuppress + +// TODO: reassess when we decide what to do with declaration annotations +- (BOOL)resignFirstResponder /* SUPPRESS */ { + return 0; +} // expected-warning {{The 'resignFirstResponder' instance method in UIResponder subclass 'TestSuppress' is missing a [super resignFirstResponder] call}} + +// TODO: reassess when we decide what to do with declaration annotations +- (void)methodWhichMayFail:(NSError **)error /* SUPPRESS */ { + // expected-warning@-1 {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}} +} +@end + +struct AB { + int A, B; +}; + +struct ABC { + int A, B, C; +}; + +void ast_checker_1() { + struct AB Ab; + struct ABC *Abc; + Abc = (struct ABC *)&Ab; // expected-warning {{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}} +} + +void ast_checker_suppress_1() { + struct AB Ab; + struct ABC *Abc; + SUPPRESS { Abc = (struct ABC *)&Ab; } +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index eac9ac0e827982c38728e9653b9b53d88251bbff..2bceb3e267790db5cba458d71796b5b947e83691 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -1,4 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -verify %s +// The following narrowing does not involve const references, so +// -Wno-c++11-narrowing-const-reference does not suppress the errors. +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -Wno-c++11-narrowing-const-reference -verify %s // Verify that narrowing conversions in initializer lists cause errors in C++0x // mode. diff --git a/clang/test/ClangScanDeps/strip-llvm-args.m b/clang/test/ClangScanDeps/strip-llvm-args.m new file mode 100644 index 0000000000000000000000000000000000000000..ca8eab7729232b16d08fdcc8b3631155943bd638 --- /dev/null +++ b/clang/test/ClangScanDeps/strip-llvm-args.m @@ -0,0 +1,46 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb1.json.template > %t/cdb1.json + +// RUN: clang-scan-deps -compilation-database %t/cdb1.json -format experimental-full > %t/result1.txt +// RUN: FileCheck %s -input-file %t/result1.txt + +// CHECK: "modules": [ +// CHECK-NEXT: { +// CHECK: "command-line": [ +// CHECK-NOT: "-mllvm" +// CHECK: ] +// CHECK: "name": "A" +// CHECK: } +// CHECK-NOT: "name": "A" +// CHECK: "translation-units" + +//--- cdb1.json.template +[ + { + "directory": "DIR", + "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -fsyntax-only DIR/t1.m", + "file": "DIR/t1.m" + }, + { + "directory": "DIR", + "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -mllvm -stackmap-version=2 -fsyntax-only DIR/t2.m", + "file": "DIR/t2.m" + } +] + +//--- modules/A/module.modulemap + +module A { + umbrella header "A.h" +} + +//--- modules/A/A.h + +typedef int A_t; + +//--- t1.m +@import A; + +//--- t2.m +@import A; diff --git a/clang/test/CodeGen/LoongArch/lasx/builtin-alias.c b/clang/test/CodeGen/LoongArch/lasx/builtin-alias.c index 09b2d5fcacf5303bdb32ec93a0353bcb36fb87d3..9a8ce224bcfd0910914c54519f8c263d4f6fa379 100644 --- a/clang/test/CodeGen/LoongArch/lasx/builtin-alias.c +++ b/clang/test/CodeGen/LoongArch/lasx/builtin-alias.c @@ -5,4426 +5,6382 @@ // CHECK-LABEL: @xvsll_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsll.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsll.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsll_b(v32i8 _1, v32i8 _2) { return __lasx_xvsll_b(_1, _2); } // CHECK-LABEL: @xvsll_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsll.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsll.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsll_h(v16i16 _1, v16i16 _2) { return __lasx_xvsll_h(_1, _2); } // CHECK-LABEL: @xvsll_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsll.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsll.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsll_w(v8i32 _1, v8i32 _2) { return __lasx_xvsll_w(_1, _2); } // CHECK-LABEL: @xvsll_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsll.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsll.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsll_d(v4i64 _1, v4i64 _2) { return __lasx_xvsll_d(_1, _2); } // CHECK-LABEL: @xvslli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslli_b(v32i8 _1) { return __lasx_xvslli_b(_1, 1); } // CHECK-LABEL: @xvslli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslli_h(v16i16 _1) { return __lasx_xvslli_h(_1, 1); } // CHECK-LABEL: @xvslli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslli_w(v8i32 _1) { return __lasx_xvslli_w(_1, 1); } // CHECK-LABEL: @xvslli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslli_d(v4i64 _1) { return __lasx_xvslli_d(_1, 1); } // CHECK-LABEL: @xvsra_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsra.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsra.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsra_b(v32i8 _1, v32i8 _2) { return __lasx_xvsra_b(_1, _2); } // CHECK-LABEL: @xvsra_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsra.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsra.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsra_h(v16i16 _1, v16i16 _2) { return __lasx_xvsra_h(_1, _2); } // CHECK-LABEL: @xvsra_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsra.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsra.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsra_w(v8i32 _1, v8i32 _2) { return __lasx_xvsra_w(_1, _2); } // CHECK-LABEL: @xvsra_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsra.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsra.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsra_d(v4i64 _1, v4i64 _2) { return __lasx_xvsra_d(_1, _2); } // CHECK-LABEL: @xvsrai_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrai_b(v32i8 _1) { return __lasx_xvsrai_b(_1, 1); } // CHECK-LABEL: @xvsrai_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrai_h(v16i16 _1) { return __lasx_xvsrai_h(_1, 1); } // CHECK-LABEL: @xvsrai_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrai_w(v8i32 _1) { return __lasx_xvsrai_w(_1, 1); } // CHECK-LABEL: @xvsrai_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrai_d(v4i64 _1) { return __lasx_xvsrai_d(_1, 1); } // CHECK-LABEL: @xvsrar_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrar.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrar.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrar_b(v32i8 _1, v32i8 _2) { return __lasx_xvsrar_b(_1, _2); } // CHECK-LABEL: @xvsrar_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrar.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrar.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrar_h(v16i16 _1, v16i16 _2) { return __lasx_xvsrar_h(_1, _2); } // CHECK-LABEL: @xvsrar_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrar.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrar.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrar_w(v8i32 _1, v8i32 _2) { return __lasx_xvsrar_w(_1, _2); } // CHECK-LABEL: @xvsrar_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrar.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrar.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrar_d(v4i64 _1, v4i64 _2) { return __lasx_xvsrar_d(_1, _2); } // CHECK-LABEL: @xvsrari_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrari_b(v32i8 _1) { return __lasx_xvsrari_b(_1, 1); } // CHECK-LABEL: @xvsrari_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrari_h(v16i16 _1) { return __lasx_xvsrari_h(_1, 1); } // CHECK-LABEL: @xvsrari_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrari_w(v8i32 _1) { return __lasx_xvsrari_w(_1, 1); } // CHECK-LABEL: @xvsrari_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrari_d(v4i64 _1) { return __lasx_xvsrari_d(_1, 1); } // CHECK-LABEL: @xvsrl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrl.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrl.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrl_b(v32i8 _1, v32i8 _2) { return __lasx_xvsrl_b(_1, _2); } // CHECK-LABEL: @xvsrl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrl.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrl.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrl_h(v16i16 _1, v16i16 _2) { return __lasx_xvsrl_h(_1, _2); } // CHECK-LABEL: @xvsrl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrl.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrl.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrl_w(v8i32 _1, v8i32 _2) { return __lasx_xvsrl_w(_1, _2); } // CHECK-LABEL: @xvsrl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrl.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrl.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrl_d(v4i64 _1, v4i64 _2) { return __lasx_xvsrl_d(_1, _2); } // CHECK-LABEL: @xvsrli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrli_b(v32i8 _1) { return __lasx_xvsrli_b(_1, 1); } // CHECK-LABEL: @xvsrli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrli_h(v16i16 _1) { return __lasx_xvsrli_h(_1, 1); } // CHECK-LABEL: @xvsrli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrli_w(v8i32 _1) { return __lasx_xvsrli_w(_1, 1); } // CHECK-LABEL: @xvsrli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrli_d(v4i64 _1) { return __lasx_xvsrli_d(_1, 1); } // CHECK-LABEL: @xvsrlr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlr.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlr_b(v32i8 _1, v32i8 _2) { return __lasx_xvsrlr_b(_1, _2); } // CHECK-LABEL: @xvsrlr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlr.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlr_h(v16i16 _1, v16i16 _2) { return __lasx_xvsrlr_h(_1, _2); } // CHECK-LABEL: @xvsrlr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlr.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlr_w(v8i32 _1, v8i32 _2) { return __lasx_xvsrlr_w(_1, _2); } // CHECK-LABEL: @xvsrlr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlr_d(v4i64 _1, v4i64 _2) { return __lasx_xvsrlr_d(_1, _2); } // CHECK-LABEL: @xvsrlri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlri_b(v32i8 _1) { return __lasx_xvsrlri_b(_1, 1); } // CHECK-LABEL: @xvsrlri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlri_h(v16i16 _1) { return __lasx_xvsrlri_h(_1, 1); } // CHECK-LABEL: @xvsrlri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlri_w(v8i32 _1) { return __lasx_xvsrlri_w(_1, 1); } // CHECK-LABEL: @xvsrlri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlri_d(v4i64 _1) { return __lasx_xvsrlri_d(_1, 1); } // CHECK-LABEL: @xvbitclr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclr.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitclr_b(v32u8 _1, v32u8 _2) { return __lasx_xvbitclr_b(_1, _2); } // CHECK-LABEL: @xvbitclr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclr.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitclr_h(v16u16 _1, v16u16 _2) { return __lasx_xvbitclr_h(_1, _2); } // CHECK-LABEL: @xvbitclr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclr.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitclr_w(v8u32 _1, v8u32 _2) { return __lasx_xvbitclr_w(_1, _2); } // CHECK-LABEL: @xvbitclr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitclr_d(v4u64 _1, v4u64 _2) { return __lasx_xvbitclr_d(_1, _2); } // CHECK-LABEL: @xvbitclri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitclri_b(v32u8 _1) { return __lasx_xvbitclri_b(_1, 1); } // CHECK-LABEL: @xvbitclri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitclri_h(v16u16 _1) { return __lasx_xvbitclri_h(_1, 1); } // CHECK-LABEL: @xvbitclri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitclri_w(v8u32 _1) { return __lasx_xvbitclri_w(_1, 1); } // CHECK-LABEL: @xvbitclri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitclri_d(v4u64 _1) { return __lasx_xvbitclri_d(_1, 1); } // CHECK-LABEL: @xvbitset_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitset.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitset.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitset_b(v32u8 _1, v32u8 _2) { return __lasx_xvbitset_b(_1, _2); } // CHECK-LABEL: @xvbitset_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitset.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitset.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitset_h(v16u16 _1, v16u16 _2) { return __lasx_xvbitset_h(_1, _2); } // CHECK-LABEL: @xvbitset_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitset.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitset.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitset_w(v8u32 _1, v8u32 _2) { return __lasx_xvbitset_w(_1, _2); } // CHECK-LABEL: @xvbitset_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitset.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitset.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitset_d(v4u64 _1, v4u64 _2) { return __lasx_xvbitset_d(_1, _2); } // CHECK-LABEL: @xvbitseti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitseti_b(v32u8 _1) { return __lasx_xvbitseti_b(_1, 1); } // CHECK-LABEL: @xvbitseti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitseti_h(v16u16 _1) { return __lasx_xvbitseti_h(_1, 1); } // CHECK-LABEL: @xvbitseti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitseti_w(v8u32 _1) { return __lasx_xvbitseti_w(_1, 1); } // CHECK-LABEL: @xvbitseti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitseti_d(v4u64 _1) { return __lasx_xvbitseti_d(_1, 1); } // CHECK-LABEL: @xvbitrev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrev.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrev.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitrev_b(v32u8 _1, v32u8 _2) { return __lasx_xvbitrev_b(_1, _2); } // CHECK-LABEL: @xvbitrev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrev.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrev.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitrev_h(v16u16 _1, v16u16 _2) { return __lasx_xvbitrev_h(_1, _2); } // CHECK-LABEL: @xvbitrev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrev.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrev.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitrev_w(v8u32 _1, v8u32 _2) { return __lasx_xvbitrev_w(_1, _2); } // CHECK-LABEL: @xvbitrev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrev.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrev.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitrev_d(v4u64 _1, v4u64 _2) { return __lasx_xvbitrev_d(_1, _2); } // CHECK-LABEL: @xvbitrevi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitrevi_b(v32u8 _1) { return __lasx_xvbitrevi_b(_1, 1); } // CHECK-LABEL: @xvbitrevi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitrevi_h(v16u16 _1) { return __lasx_xvbitrevi_h(_1, 1); } // CHECK-LABEL: @xvbitrevi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitrevi_w(v8u32 _1) { return __lasx_xvbitrevi_w(_1, 1); } // CHECK-LABEL: @xvbitrevi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitrevi_d(v4u64 _1) { return __lasx_xvbitrevi_d(_1, 1); } // CHECK-LABEL: @xvadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadd.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvadd_b(v32i8 _1, v32i8 _2) { return __lasx_xvadd_b(_1, _2); } // CHECK-LABEL: @xvadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadd.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvadd_h(v16i16 _1, v16i16 _2) { return __lasx_xvadd_h(_1, _2); } // CHECK-LABEL: @xvadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadd.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvadd_w(v8i32 _1, v8i32 _2) { return __lasx_xvadd_w(_1, _2); } // CHECK-LABEL: @xvadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvadd_d(v4i64 _1, v4i64 _2) { return __lasx_xvadd_d(_1, _2); } // CHECK-LABEL: @xvaddi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvaddi_bu(v32i8 _1) { return __lasx_xvaddi_bu(_1, 1); } // CHECK-LABEL: @xvaddi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddi_hu(v16i16 _1) { return __lasx_xvaddi_hu(_1, 1); } // CHECK-LABEL: @xvaddi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddi_wu(v8i32 _1) { return __lasx_xvaddi_wu(_1, 1); } // CHECK-LABEL: @xvaddi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddi_du(v4i64 _1) { return __lasx_xvaddi_du(_1, 1); } // CHECK-LABEL: @xvsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsub.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsub.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsub_b(v32i8 _1, v32i8 _2) { return __lasx_xvsub_b(_1, _2); } // CHECK-LABEL: @xvsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsub.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsub.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsub_h(v16i16 _1, v16i16 _2) { return __lasx_xvsub_h(_1, _2); } // CHECK-LABEL: @xvsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsub_w(v8i32 _1, v8i32 _2) { return __lasx_xvsub_w(_1, _2); } // CHECK-LABEL: @xvsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsub_d(v4i64 _1, v4i64 _2) { return __lasx_xvsub_d(_1, _2); } // CHECK-LABEL: @xvsubi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsubi_bu(v32i8 _1) { return __lasx_xvsubi_bu(_1, 1); } // CHECK-LABEL: @xvsubi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubi_hu(v16i16 _1) { return __lasx_xvsubi_hu(_1, 1); } // CHECK-LABEL: @xvsubi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubi_wu(v8i32 _1) { return __lasx_xvsubi_wu(_1, 1); } // CHECK-LABEL: @xvsubi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubi_du(v4i64 _1) { return __lasx_xvsubi_du(_1, 1); } // CHECK-LABEL: @xvmax_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmax_b(v32i8 _1, v32i8 _2) { return __lasx_xvmax_b(_1, _2); } // CHECK-LABEL: @xvmax_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmax_h(v16i16 _1, v16i16 _2) { return __lasx_xvmax_h(_1, _2); } // CHECK-LABEL: @xvmax_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmax_w(v8i32 _1, v8i32 _2) { return __lasx_xvmax_w(_1, _2); } // CHECK-LABEL: @xvmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmax_d(v4i64 _1, v4i64 _2) { return __lasx_xvmax_d(_1, _2); } // CHECK-LABEL: @xvmaxi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmaxi_b(v32i8 _1) { return __lasx_xvmaxi_b(_1, 1); } // CHECK-LABEL: @xvmaxi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaxi_h(v16i16 _1) { return __lasx_xvmaxi_h(_1, 1); } // CHECK-LABEL: @xvmaxi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaxi_w(v8i32 _1) { return __lasx_xvmaxi_w(_1, 1); } // CHECK-LABEL: @xvmaxi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaxi_d(v4i64 _1) { return __lasx_xvmaxi_d(_1, 1); } // CHECK-LABEL: @xvmax_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmax_bu(v32u8 _1, v32u8 _2) { return __lasx_xvmax_bu(_1, _2); } // CHECK-LABEL: @xvmax_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmax_hu(v16u16 _1, v16u16 _2) { return __lasx_xvmax_hu(_1, _2); } // CHECK-LABEL: @xvmax_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmax_wu(v8u32 _1, v8u32 _2) { return __lasx_xvmax_wu(_1, _2); } // CHECK-LABEL: @xvmax_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmax_du(v4u64 _1, v4u64 _2) { return __lasx_xvmax_du(_1, _2); } // CHECK-LABEL: @xvmaxi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmaxi_bu(v32u8 _1) { return __lasx_xvmaxi_bu(_1, 1); } // CHECK-LABEL: @xvmaxi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmaxi_hu(v16u16 _1) { return __lasx_xvmaxi_hu(_1, 1); } // CHECK-LABEL: @xvmaxi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmaxi_wu(v8u32 _1) { return __lasx_xvmaxi_wu(_1, 1); } // CHECK-LABEL: @xvmaxi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaxi_du(v4u64 _1) { return __lasx_xvmaxi_du(_1, 1); } // CHECK-LABEL: @xvmin_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmin_b(v32i8 _1, v32i8 _2) { return __lasx_xvmin_b(_1, _2); } // CHECK-LABEL: @xvmin_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmin_h(v16i16 _1, v16i16 _2) { return __lasx_xvmin_h(_1, _2); } // CHECK-LABEL: @xvmin_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmin_w(v8i32 _1, v8i32 _2) { return __lasx_xvmin_w(_1, _2); } // CHECK-LABEL: @xvmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmin_d(v4i64 _1, v4i64 _2) { return __lasx_xvmin_d(_1, _2); } // CHECK-LABEL: @xvmini_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmini_b(v32i8 _1) { return __lasx_xvmini_b(_1, 1); } // CHECK-LABEL: @xvmini_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmini_h(v16i16 _1) { return __lasx_xvmini_h(_1, 1); } // CHECK-LABEL: @xvmini_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmini_w(v8i32 _1) { return __lasx_xvmini_w(_1, 1); } // CHECK-LABEL: @xvmini_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmini_d(v4i64 _1) { return __lasx_xvmini_d(_1, 1); } // CHECK-LABEL: @xvmin_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmin_bu(v32u8 _1, v32u8 _2) { return __lasx_xvmin_bu(_1, _2); } // CHECK-LABEL: @xvmin_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmin_hu(v16u16 _1, v16u16 _2) { return __lasx_xvmin_hu(_1, _2); } // CHECK-LABEL: @xvmin_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmin_wu(v8u32 _1, v8u32 _2) { return __lasx_xvmin_wu(_1, _2); } // CHECK-LABEL: @xvmin_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmin_du(v4u64 _1, v4u64 _2) { return __lasx_xvmin_du(_1, _2); } // CHECK-LABEL: @xvmini_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmini_bu(v32u8 _1) { return __lasx_xvmini_bu(_1, 1); } // CHECK-LABEL: @xvmini_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmini_hu(v16u16 _1) { return __lasx_xvmini_hu(_1, 1); } // CHECK-LABEL: @xvmini_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmini_wu(v8u32 _1) { return __lasx_xvmini_wu(_1, 1); } // CHECK-LABEL: @xvmini_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmini_du(v4u64 _1) { return __lasx_xvmini_du(_1, 1); } // CHECK-LABEL: @xvseq_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseq.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseq.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvseq_b(v32i8 _1, v32i8 _2) { return __lasx_xvseq_b(_1, _2); } // CHECK-LABEL: @xvseq_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseq.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseq.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvseq_h(v16i16 _1, v16i16 _2) { return __lasx_xvseq_h(_1, _2); } // CHECK-LABEL: @xvseq_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseq.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseq.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvseq_w(v8i32 _1, v8i32 _2) { return __lasx_xvseq_w(_1, _2); } // CHECK-LABEL: @xvseq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseq.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseq.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvseq_d(v4i64 _1, v4i64 _2) { return __lasx_xvseq_d(_1, _2); } // CHECK-LABEL: @xvseqi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvseqi_b(v32i8 _1) { return __lasx_xvseqi_b(_1, 1); } // CHECK-LABEL: @xvseqi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvseqi_h(v16i16 _1) { return __lasx_xvseqi_h(_1, 1); } // CHECK-LABEL: @xvseqi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvseqi_w(v8i32 _1) { return __lasx_xvseqi_w(_1, 1); } // CHECK-LABEL: @xvseqi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvseqi_d(v4i64 _1) { return __lasx_xvseqi_d(_1, 1); } // CHECK-LABEL: @xvslt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslt_b(v32i8 _1, v32i8 _2) { return __lasx_xvslt_b(_1, _2); } // CHECK-LABEL: @xvslt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslt_h(v16i16 _1, v16i16 _2) { return __lasx_xvslt_h(_1, _2); } // CHECK-LABEL: @xvslt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslt_w(v8i32 _1, v8i32 _2) { return __lasx_xvslt_w(_1, _2); } // CHECK-LABEL: @xvslt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslt_d(v4i64 _1, v4i64 _2) { return __lasx_xvslt_d(_1, _2); } // CHECK-LABEL: @xvslti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslti_b(v32i8 _1) { return __lasx_xvslti_b(_1, 1); } // CHECK-LABEL: @xvslti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslti_h(v16i16 _1) { return __lasx_xvslti_h(_1, 1); } // CHECK-LABEL: @xvslti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslti_w(v8i32 _1) { return __lasx_xvslti_w(_1, 1); } // CHECK-LABEL: @xvslti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslti_d(v4i64 _1) { return __lasx_xvslti_d(_1, 1); } // CHECK-LABEL: @xvslt_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslt_bu(v32u8 _1, v32u8 _2) { return __lasx_xvslt_bu(_1, _2); } // CHECK-LABEL: @xvslt_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslt_hu(v16u16 _1, v16u16 _2) { return __lasx_xvslt_hu(_1, _2); } // CHECK-LABEL: @xvslt_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslt_wu(v8u32 _1, v8u32 _2) { return __lasx_xvslt_wu(_1, _2); } // CHECK-LABEL: @xvslt_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslt_du(v4u64 _1, v4u64 _2) { return __lasx_xvslt_du(_1, _2); } // CHECK-LABEL: @xvslti_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslti_bu(v32u8 _1) { return __lasx_xvslti_bu(_1, 1); } // CHECK-LABEL: @xvslti_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslti_hu(v16u16 _1) { return __lasx_xvslti_hu(_1, 1); } // CHECK-LABEL: @xvslti_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslti_wu(v8u32 _1) { return __lasx_xvslti_wu(_1, 1); } // CHECK-LABEL: @xvslti_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslti_du(v4u64 _1) { return __lasx_xvslti_du(_1, 1); } // CHECK-LABEL: @xvsle_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsle_b(v32i8 _1, v32i8 _2) { return __lasx_xvsle_b(_1, _2); } // CHECK-LABEL: @xvsle_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsle_h(v16i16 _1, v16i16 _2) { return __lasx_xvsle_h(_1, _2); } // CHECK-LABEL: @xvsle_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsle_w(v8i32 _1, v8i32 _2) { return __lasx_xvsle_w(_1, _2); } // CHECK-LABEL: @xvsle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsle_d(v4i64 _1, v4i64 _2) { return __lasx_xvsle_d(_1, _2); } // CHECK-LABEL: @xvslei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslei_b(v32i8 _1) { return __lasx_xvslei_b(_1, 1); } // CHECK-LABEL: @xvslei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslei_h(v16i16 _1) { return __lasx_xvslei_h(_1, 1); } // CHECK-LABEL: @xvslei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslei_w(v8i32 _1) { return __lasx_xvslei_w(_1, 1); } // CHECK-LABEL: @xvslei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslei_d(v4i64 _1) { return __lasx_xvslei_d(_1, 1); } // CHECK-LABEL: @xvsle_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsle_bu(v32u8 _1, v32u8 _2) { return __lasx_xvsle_bu(_1, _2); } // CHECK-LABEL: @xvsle_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsle_hu(v16u16 _1, v16u16 _2) { return __lasx_xvsle_hu(_1, _2); } // CHECK-LABEL: @xvsle_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsle_wu(v8u32 _1, v8u32 _2) { return __lasx_xvsle_wu(_1, _2); } // CHECK-LABEL: @xvsle_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsle_du(v4u64 _1, v4u64 _2) { return __lasx_xvsle_du(_1, _2); } // CHECK-LABEL: @xvslei_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslei_bu(v32u8 _1) { return __lasx_xvslei_bu(_1, 1); } // CHECK-LABEL: @xvslei_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslei_hu(v16u16 _1) { return __lasx_xvslei_hu(_1, 1); } // CHECK-LABEL: @xvslei_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslei_wu(v8u32 _1) { return __lasx_xvslei_wu(_1, 1); } // CHECK-LABEL: @xvslei_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslei_du(v4u64 _1) { return __lasx_xvslei_du(_1, 1); } // CHECK-LABEL: @xvsat_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsat_b(v32i8 _1) { return __lasx_xvsat_b(_1, 1); } // CHECK-LABEL: @xvsat_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsat_h(v16i16 _1) { return __lasx_xvsat_h(_1, 1); } // CHECK-LABEL: @xvsat_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsat_w(v8i32 _1) { return __lasx_xvsat_w(_1, 1); } // CHECK-LABEL: @xvsat_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsat_d(v4i64 _1) { return __lasx_xvsat_d(_1, 1); } // CHECK-LABEL: @xvsat_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvsat_bu(v32u8 _1) { return __lasx_xvsat_bu(_1, 1); } // CHECK-LABEL: @xvsat_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvsat_hu(v16u16 _1) { return __lasx_xvsat_hu(_1, 1); } // CHECK-LABEL: @xvsat_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvsat_wu(v8u32 _1) { return __lasx_xvsat_wu(_1, 1); } // CHECK-LABEL: @xvsat_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvsat_du(v4u64 _1) { return __lasx_xvsat_du(_1, 1); } // CHECK-LABEL: @xvadda_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadda.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadda.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvadda_b(v32i8 _1, v32i8 _2) { return __lasx_xvadda_b(_1, _2); } // CHECK-LABEL: @xvadda_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadda.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadda.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvadda_h(v16i16 _1, v16i16 _2) { return __lasx_xvadda_h(_1, _2); } // CHECK-LABEL: @xvadda_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadda.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadda.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvadda_w(v8i32 _1, v8i32 _2) { return __lasx_xvadda_w(_1, _2); } // CHECK-LABEL: @xvadda_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadda.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadda.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvadda_d(v4i64 _1, v4i64 _2) { return __lasx_xvadda_d(_1, _2); } // CHECK-LABEL: @xvsadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsadd_b(v32i8 _1, v32i8 _2) { return __lasx_xvsadd_b(_1, _2); } // CHECK-LABEL: @xvsadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsadd_h(v16i16 _1, v16i16 _2) { return __lasx_xvsadd_h(_1, _2); } // CHECK-LABEL: @xvsadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsadd_w(v8i32 _1, v8i32 _2) { return __lasx_xvsadd_w(_1, _2); } // CHECK-LABEL: @xvsadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsadd_d(v4i64 _1, v4i64 _2) { return __lasx_xvsadd_d(_1, _2); } // CHECK-LABEL: @xvsadd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvsadd_bu(v32u8 _1, v32u8 _2) { return __lasx_xvsadd_bu(_1, _2); } // CHECK-LABEL: @xvsadd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvsadd_hu(v16u16 _1, v16u16 _2) { return __lasx_xvsadd_hu(_1, _2); } // CHECK-LABEL: @xvsadd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvsadd_wu(v8u32 _1, v8u32 _2) { return __lasx_xvsadd_wu(_1, _2); } // CHECK-LABEL: @xvsadd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvsadd_du(v4u64 _1, v4u64 _2) { return __lasx_xvsadd_du(_1, _2); } // CHECK-LABEL: @xvavg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvavg_b(v32i8 _1, v32i8 _2) { return __lasx_xvavg_b(_1, _2); } // CHECK-LABEL: @xvavg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvavg_h(v16i16 _1, v16i16 _2) { return __lasx_xvavg_h(_1, _2); } // CHECK-LABEL: @xvavg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvavg_w(v8i32 _1, v8i32 _2) { return __lasx_xvavg_w(_1, _2); } // CHECK-LABEL: @xvavg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvavg_d(v4i64 _1, v4i64 _2) { return __lasx_xvavg_d(_1, _2); } // CHECK-LABEL: @xvavg_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvavg_bu(v32u8 _1, v32u8 _2) { return __lasx_xvavg_bu(_1, _2); } // CHECK-LABEL: @xvavg_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvavg_hu(v16u16 _1, v16u16 _2) { return __lasx_xvavg_hu(_1, _2); } // CHECK-LABEL: @xvavg_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvavg_wu(v8u32 _1, v8u32 _2) { return __lasx_xvavg_wu(_1, _2); } // CHECK-LABEL: @xvavg_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvavg_du(v4u64 _1, v4u64 _2) { return __lasx_xvavg_du(_1, _2); } // CHECK-LABEL: @xvavgr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvavgr_b(v32i8 _1, v32i8 _2) { return __lasx_xvavgr_b(_1, _2); } // CHECK-LABEL: @xvavgr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvavgr_h(v16i16 _1, v16i16 _2) { return __lasx_xvavgr_h(_1, _2); } // CHECK-LABEL: @xvavgr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvavgr_w(v8i32 _1, v8i32 _2) { return __lasx_xvavgr_w(_1, _2); } // CHECK-LABEL: @xvavgr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvavgr_d(v4i64 _1, v4i64 _2) { return __lasx_xvavgr_d(_1, _2); } // CHECK-LABEL: @xvavgr_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvavgr_bu(v32u8 _1, v32u8 _2) { return __lasx_xvavgr_bu(_1, _2); } // CHECK-LABEL: @xvavgr_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvavgr_hu(v16u16 _1, v16u16 _2) { return __lasx_xvavgr_hu(_1, _2); } // CHECK-LABEL: @xvavgr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvavgr_wu(v8u32 _1, v8u32 _2) { return __lasx_xvavgr_wu(_1, _2); } // CHECK-LABEL: @xvavgr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvavgr_du(v4u64 _1, v4u64 _2) { return __lasx_xvavgr_du(_1, _2); } // CHECK-LABEL: @xvssub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssub_b(v32i8 _1, v32i8 _2) { return __lasx_xvssub_b(_1, _2); } // CHECK-LABEL: @xvssub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssub_h(v16i16 _1, v16i16 _2) { return __lasx_xvssub_h(_1, _2); } // CHECK-LABEL: @xvssub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssub_w(v8i32 _1, v8i32 _2) { return __lasx_xvssub_w(_1, _2); } // CHECK-LABEL: @xvssub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssub_d(v4i64 _1, v4i64 _2) { return __lasx_xvssub_d(_1, _2); } // CHECK-LABEL: @xvssub_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssub_bu(v32u8 _1, v32u8 _2) { return __lasx_xvssub_bu(_1, _2); } // CHECK-LABEL: @xvssub_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssub_hu(v16u16 _1, v16u16 _2) { return __lasx_xvssub_hu(_1, _2); } // CHECK-LABEL: @xvssub_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssub_wu(v8u32 _1, v8u32 _2) { return __lasx_xvssub_wu(_1, _2); } // CHECK-LABEL: @xvssub_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssub_du(v4u64 _1, v4u64 _2) { return __lasx_xvssub_du(_1, _2); } // CHECK-LABEL: @xvabsd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvabsd_b(v32i8 _1, v32i8 _2) { return __lasx_xvabsd_b(_1, _2); } // CHECK-LABEL: @xvabsd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvabsd_h(v16i16 _1, v16i16 _2) { return __lasx_xvabsd_h(_1, _2); } // CHECK-LABEL: @xvabsd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvabsd_w(v8i32 _1, v8i32 _2) { return __lasx_xvabsd_w(_1, _2); } // CHECK-LABEL: @xvabsd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvabsd_d(v4i64 _1, v4i64 _2) { return __lasx_xvabsd_d(_1, _2); } // CHECK-LABEL: @xvabsd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvabsd_bu(v32u8 _1, v32u8 _2) { return __lasx_xvabsd_bu(_1, _2); } // CHECK-LABEL: @xvabsd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvabsd_hu(v16u16 _1, v16u16 _2) { return __lasx_xvabsd_hu(_1, _2); } // CHECK-LABEL: @xvabsd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvabsd_wu(v8u32 _1, v8u32 _2) { return __lasx_xvabsd_wu(_1, _2); } // CHECK-LABEL: @xvabsd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvabsd_du(v4u64 _1, v4u64 _2) { return __lasx_xvabsd_du(_1, _2); } // CHECK-LABEL: @xvmul_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmul.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmul.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmul_b(v32i8 _1, v32i8 _2) { return __lasx_xvmul_b(_1, _2); } // CHECK-LABEL: @xvmul_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmul.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmul.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmul_h(v16i16 _1, v16i16 _2) { return __lasx_xvmul_h(_1, _2); } // CHECK-LABEL: @xvmul_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmul.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmul.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmul_w(v8i32 _1, v8i32 _2) { return __lasx_xvmul_w(_1, _2); } // CHECK-LABEL: @xvmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmul.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmul.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmul_d(v4i64 _1, v4i64 _2) { return __lasx_xvmul_d(_1, _2); } // CHECK-LABEL: @xvmadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmadd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmadd.b(<32 x i8> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmadd_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __lasx_xvmadd_b(_1, _2, _3); } // CHECK-LABEL: @xvmadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmadd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmadd.h(<16 x i16> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmadd_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __lasx_xvmadd_h(_1, _2, _3); } // CHECK-LABEL: @xvmadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmadd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmadd.w(<8 x i32> [[_136]], <8 x i32> [[_247]], <8 x i32> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmadd_w(v8i32 _1, v8i32 _2, v8i32 _3) { return __lasx_xvmadd_w(_1, _2, _3); } // CHECK-LABEL: @xvmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmadd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmadd.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmadd_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __lasx_xvmadd_d(_1, _2, _3); } // CHECK-LABEL: @xvmsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsub.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsub.b(<32 x i8> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmsub_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __lasx_xvmsub_b(_1, _2, _3); } // CHECK-LABEL: @xvmsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmsub.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmsub.h(<16 x i16> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmsub_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __lasx_xvmsub_h(_1, _2, _3); } // CHECK-LABEL: @xvmsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmsub.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmsub.w(<8 x i32> [[_136]], <8 x i32> [[_247]], <8 x i32> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmsub_w(v8i32 _1, v8i32 _2, v8i32 _3) { return __lasx_xvmsub_w(_1, _2, _3); } // CHECK-LABEL: @xvmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmsub.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmsub.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmsub_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __lasx_xvmsub_d(_1, _2, _3); } // CHECK-LABEL: @xvdiv_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvdiv_b(v32i8 _1, v32i8 _2) { return __lasx_xvdiv_b(_1, _2); } // CHECK-LABEL: @xvdiv_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvdiv_h(v16i16 _1, v16i16 _2) { return __lasx_xvdiv_h(_1, _2); } // CHECK-LABEL: @xvdiv_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvdiv_w(v8i32 _1, v8i32 _2) { return __lasx_xvdiv_w(_1, _2); } // CHECK-LABEL: @xvdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvdiv_d(v4i64 _1, v4i64 _2) { return __lasx_xvdiv_d(_1, _2); } // CHECK-LABEL: @xvdiv_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvdiv_bu(v32u8 _1, v32u8 _2) { return __lasx_xvdiv_bu(_1, _2); } // CHECK-LABEL: @xvdiv_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvdiv_hu(v16u16 _1, v16u16 _2) { return __lasx_xvdiv_hu(_1, _2); } // CHECK-LABEL: @xvdiv_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvdiv_wu(v8u32 _1, v8u32 _2) { return __lasx_xvdiv_wu(_1, _2); } // CHECK-LABEL: @xvdiv_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvdiv_du(v4u64 _1, v4u64 _2) { return __lasx_xvdiv_du(_1, _2); } // CHECK-LABEL: @xvhaddw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvhaddw_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvhaddw_h_b(_1, _2); } // CHECK-LABEL: @xvhaddw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvhaddw_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvhaddw_w_h(_1, _2); } // CHECK-LABEL: @xvhaddw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhaddw_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvhaddw_d_w(_1, _2); } // CHECK-LABEL: @xvhaddw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.hu.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.hu.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvhaddw_hu_bu(v32u8 _1, v32u8 _2) { return __lasx_xvhaddw_hu_bu(_1, _2); } // CHECK-LABEL: @xvhaddw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.wu.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.wu.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvhaddw_wu_hu(v16u16 _1, v16u16 _2) { return __lasx_xvhaddw_wu_hu(_1, _2); } // CHECK-LABEL: @xvhaddw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.du.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.du.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvhaddw_du_wu(v8u32 _1, v8u32 _2) { return __lasx_xvhaddw_du_wu(_1, _2); } // CHECK-LABEL: @xvhsubw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvhsubw_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvhsubw_h_b(_1, _2); } // CHECK-LABEL: @xvhsubw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvhsubw_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvhsubw_w_h(_1, _2); } // CHECK-LABEL: @xvhsubw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhsubw_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvhsubw_d_w(_1, _2); } // CHECK-LABEL: @xvhsubw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.hu.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.hu.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvhsubw_hu_bu(v32u8 _1, v32u8 _2) { return __lasx_xvhsubw_hu_bu(_1, _2); } // CHECK-LABEL: @xvhsubw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.wu.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.wu.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvhsubw_wu_hu(v16u16 _1, v16u16 _2) { return __lasx_xvhsubw_wu_hu(_1, _2); } // CHECK-LABEL: @xvhsubw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.du.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.du.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhsubw_du_wu(v8u32 _1, v8u32 _2) { return __lasx_xvhsubw_du_wu(_1, _2); } // CHECK-LABEL: @xvmod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmod_b(v32i8 _1, v32i8 _2) { return __lasx_xvmod_b(_1, _2); } // CHECK-LABEL: @xvmod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmod_h(v16i16 _1, v16i16 _2) { return __lasx_xvmod_h(_1, _2); } // CHECK-LABEL: @xvmod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmod_w(v8i32 _1, v8i32 _2) { return __lasx_xvmod_w(_1, _2); } // CHECK-LABEL: @xvmod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmod_d(v4i64 _1, v4i64 _2) { return __lasx_xvmod_d(_1, _2); } // CHECK-LABEL: @xvmod_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmod_bu(v32u8 _1, v32u8 _2) { return __lasx_xvmod_bu(_1, _2); } // CHECK-LABEL: @xvmod_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmod_hu(v16u16 _1, v16u16 _2) { return __lasx_xvmod_hu(_1, _2); } // CHECK-LABEL: @xvmod_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmod_wu(v8u32 _1, v8u32 _2) { return __lasx_xvmod_wu(_1, _2); } // CHECK-LABEL: @xvmod_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmod_du(v4u64 _1, v4u64 _2) { return __lasx_xvmod_du(_1, _2); } // CHECK-LABEL: @xvrepl128vei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrepl128vei_b(v32i8 _1) { return __lasx_xvrepl128vei_b(_1, 1); } // CHECK-LABEL: @xvrepl128vei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrepl128vei_h(v16i16 _1) { return __lasx_xvrepl128vei_h(_1, 1); } // CHECK-LABEL: @xvrepl128vei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrepl128vei_w(v8i32 _1) { return __lasx_xvrepl128vei_w(_1, 1); } // CHECK-LABEL: @xvrepl128vei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrepl128vei_d(v4i64 _1) { return __lasx_xvrepl128vei_d(_1, 1); } // CHECK-LABEL: @xvpickev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickev.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickev.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpickev_b(v32i8 _1, v32i8 _2) { return __lasx_xvpickev_b(_1, _2); } // CHECK-LABEL: @xvpickev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickev.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickev.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpickev_h(v16i16 _1, v16i16 _2) { return __lasx_xvpickev_h(_1, _2); } // CHECK-LABEL: @xvpickev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickev.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickev.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpickev_w(v8i32 _1, v8i32 _2) { return __lasx_xvpickev_w(_1, _2); } // CHECK-LABEL: @xvpickev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickev.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickev.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpickev_d(v4i64 _1, v4i64 _2) { return __lasx_xvpickev_d(_1, _2); } // CHECK-LABEL: @xvpickod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickod.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickod.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpickod_b(v32i8 _1, v32i8 _2) { return __lasx_xvpickod_b(_1, _2); } // CHECK-LABEL: @xvpickod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickod.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickod.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpickod_h(v16i16 _1, v16i16 _2) { return __lasx_xvpickod_h(_1, _2); } // CHECK-LABEL: @xvpickod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickod.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickod.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpickod_w(v8i32 _1, v8i32 _2) { return __lasx_xvpickod_w(_1, _2); } // CHECK-LABEL: @xvpickod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickod.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickod.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpickod_d(v4i64 _1, v4i64 _2) { return __lasx_xvpickod_d(_1, _2); } // CHECK-LABEL: @xvilvh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvh.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvh.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvilvh_b(v32i8 _1, v32i8 _2) { return __lasx_xvilvh_b(_1, _2); } // CHECK-LABEL: @xvilvh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvh.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvh.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvilvh_h(v16i16 _1, v16i16 _2) { return __lasx_xvilvh_h(_1, _2); } // CHECK-LABEL: @xvilvh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvh.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvh.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvilvh_w(v8i32 _1, v8i32 _2) { return __lasx_xvilvh_w(_1, _2); } // CHECK-LABEL: @xvilvh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvh.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvh.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvilvh_d(v4i64 _1, v4i64 _2) { return __lasx_xvilvh_d(_1, _2); } // CHECK-LABEL: @xvilvl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvl.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvl.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvilvl_b(v32i8 _1, v32i8 _2) { return __lasx_xvilvl_b(_1, _2); } // CHECK-LABEL: @xvilvl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvl.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvl.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvilvl_h(v16i16 _1, v16i16 _2) { return __lasx_xvilvl_h(_1, _2); } // CHECK-LABEL: @xvilvl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvl.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvl.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvilvl_w(v8i32 _1, v8i32 _2) { return __lasx_xvilvl_w(_1, _2); } // CHECK-LABEL: @xvilvl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvl.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvl.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvilvl_d(v4i64 _1, v4i64 _2) { return __lasx_xvilvl_d(_1, _2); } // CHECK-LABEL: @xvpackev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackev.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackev.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpackev_b(v32i8 _1, v32i8 _2) { return __lasx_xvpackev_b(_1, _2); } // CHECK-LABEL: @xvpackev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackev.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackev.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpackev_h(v16i16 _1, v16i16 _2) { return __lasx_xvpackev_h(_1, _2); } // CHECK-LABEL: @xvpackev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackev.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackev.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpackev_w(v8i32 _1, v8i32 _2) { return __lasx_xvpackev_w(_1, _2); } // CHECK-LABEL: @xvpackev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackev.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackev.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpackev_d(v4i64 _1, v4i64 _2) { return __lasx_xvpackev_d(_1, _2); } // CHECK-LABEL: @xvpackod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackod.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackod.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpackod_b(v32i8 _1, v32i8 _2) { return __lasx_xvpackod_b(_1, _2); } // CHECK-LABEL: @xvpackod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackod.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackod.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpackod_h(v16i16 _1, v16i16 _2) { return __lasx_xvpackod_h(_1, _2); } // CHECK-LABEL: @xvpackod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackod.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackod.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpackod_w(v8i32 _1, v8i32 _2) { return __lasx_xvpackod_w(_1, _2); } // CHECK-LABEL: @xvpackod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackod.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackod.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpackod_d(v4i64 _1, v4i64 _2) { return __lasx_xvpackod_d(_1, _2); } // CHECK-LABEL: @xvshuf_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf.b(<32 x i8> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvshuf_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __lasx_xvshuf_b(_1, _2, _3); } // CHECK-LABEL: @xvshuf_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf.h(<16 x i16> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvshuf_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __lasx_xvshuf_h(_1, _2, _3); } // CHECK-LABEL: @xvshuf_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf.w(<8 x i32> [[_136]], <8 x i32> [[_247]], <8 x i32> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvshuf_w(v8i32 _1, v8i32 _2, v8i32 _3) { return __lasx_xvshuf_w(_1, _2, _3); } // CHECK-LABEL: @xvshuf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvshuf_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __lasx_xvshuf_d(_1, _2, _3); } // CHECK-LABEL: @xvand_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvand.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvand.v(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvand_v(v32u8 _1, v32u8 _2) { return __lasx_xvand_v(_1, _2); } // CHECK-LABEL: @xvandi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvandi_b(v32u8 _1) { return __lasx_xvandi_b(_1, 1); } // CHECK-LABEL: @xvor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvor.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvor.v(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvor_v(v32u8 _1, v32u8 _2) { return __lasx_xvor_v(_1, _2); } // CHECK-LABEL: @xvori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvori_b(v32u8 _1) { return __lasx_xvori_b(_1, 1); } // CHECK-LABEL: @xvnor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnor.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnor.v(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvnor_v(v32u8 _1, v32u8 _2) { return __lasx_xvnor_v(_1, _2); } // CHECK-LABEL: @xvnori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvnori_b(v32u8 _1) { return __lasx_xvnori_b(_1, 1); } // CHECK-LABEL: @xvxor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxor.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxor.v(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvxor_v(v32u8 _1, v32u8 _2) { return __lasx_xvxor_v(_1, _2); } // CHECK-LABEL: @xvxori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvxori_b(v32u8 _1) { return __lasx_xvxori_b(_1, 1); } // CHECK-LABEL: @xvbitsel_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitsel.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitsel.v(<32 x i8> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitsel_v(v32u8 _1, v32u8 _2, v32u8 _3) { return __lasx_xvbitsel_v(_1, _2, _3); } // CHECK-LABEL: @xvbitseli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitseli_b(v32u8 _1, v32u8 _2) { return __lasx_xvbitseli_b(_1, _2, 1); } // CHECK-LABEL: @xvshuf4i_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvshuf4i_b(v32i8 _1) { return __lasx_xvshuf4i_b(_1, 1); } // CHECK-LABEL: @xvshuf4i_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvshuf4i_h(v16i16 _1) { return __lasx_xvshuf4i_h(_1, 1); } // CHECK-LABEL: @xvshuf4i_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvshuf4i_w(v8i32 _1) { return __lasx_xvshuf4i_w(_1, 1); } // CHECK-LABEL: @xvreplgr2vr_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplgr2vr.b(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplgr2vr_b(int _1) { return __lasx_xvreplgr2vr_b(_1); } // CHECK-LABEL: @xvreplgr2vr_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplgr2vr.h(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: store <16 x i16> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvreplgr2vr_h(int _1) { return __lasx_xvreplgr2vr_h(_1); } // CHECK-LABEL: @xvreplgr2vr_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplgr2vr.w(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: store <8 x i32> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvreplgr2vr_w(int _1) { return __lasx_xvreplgr2vr_w(_1); } // CHECK-LABEL: @xvreplgr2vr_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[CONV:%.*]] = sext i32 [[_1:%.*]] to i64 // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplgr2vr.d(i64 [[CONV]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvreplgr2vr_d(int _1) { return __lasx_xvreplgr2vr_d(_1); } // CHECK-LABEL: @xvpcnt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpcnt.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpcnt.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpcnt_b(v32i8 _1) { return __lasx_xvpcnt_b(_1); } // CHECK-LABEL: @xvpcnt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpcnt.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpcnt.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpcnt_h(v16i16 _1) { return __lasx_xvpcnt_h(_1); } // CHECK-LABEL: @xvpcnt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpcnt.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpcnt.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpcnt_w(v8i32 _1) { return __lasx_xvpcnt_w(_1); } // CHECK-LABEL: @xvpcnt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpcnt.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpcnt.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpcnt_d(v4i64 _1) { return __lasx_xvpcnt_d(_1); } // CHECK-LABEL: @xvclo_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclo.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclo.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvclo_b(v32i8 _1) { return __lasx_xvclo_b(_1); } // CHECK-LABEL: @xvclo_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclo.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclo.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvclo_h(v16i16 _1) { return __lasx_xvclo_h(_1); } // CHECK-LABEL: @xvclo_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclo.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclo.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvclo_w(v8i32 _1) { return __lasx_xvclo_w(_1); } // CHECK-LABEL: @xvclo_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclo.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclo.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvclo_d(v4i64 _1) { return __lasx_xvclo_d(_1); } // CHECK-LABEL: @xvclz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclz.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvclz_b(v32i8 _1) { return __lasx_xvclz_b(_1); } // CHECK-LABEL: @xvclz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclz.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvclz_h(v16i16 _1) { return __lasx_xvclz_h(_1); } // CHECK-LABEL: @xvclz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclz.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvclz_w(v8i32 _1) { return __lasx_xvclz_w(_1); } // CHECK-LABEL: @xvclz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvclz_d(v4i64 _1) { return __lasx_xvclz_d(_1); } // CHECK-LABEL: @xvfadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfadd.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfadd.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfadd_s(v8f32 _1, v8f32 _2) { return __lasx_xvfadd_s(_1, _2); } // CHECK-LABEL: @xvfadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfadd.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfadd.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfadd_d(v4f64 _1, v4f64 _2) { return __lasx_xvfadd_d(_1, _2); } // CHECK-LABEL: @xvfsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsub.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsub.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfsub_s(v8f32 _1, v8f32 _2) { return __lasx_xvfsub_s(_1, _2); } // CHECK-LABEL: @xvfsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsub.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsub.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfsub_d(v4f64 _1, v4f64 _2) { return __lasx_xvfsub_d(_1, _2); } // CHECK-LABEL: @xvfmul_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmul.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmul.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmul_s(v8f32 _1, v8f32 _2) { return __lasx_xvfmul_s(_1, _2); } // CHECK-LABEL: @xvfmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmul.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmul.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmul_d(v4f64 _1, v4f64 _2) { return __lasx_xvfmul_d(_1, _2); } // CHECK-LABEL: @xvfdiv_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfdiv.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfdiv.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfdiv_s(v8f32 _1, v8f32 _2) { return __lasx_xvfdiv_s(_1, _2); } // CHECK-LABEL: @xvfdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfdiv.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfdiv.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfdiv_d(v4f64 _1, v4f64 _2) { return __lasx_xvfdiv_d(_1, _2); } // CHECK-LABEL: @xvfcvt_h_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfcvt.h.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfcvt.h.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvfcvt_h_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcvt_h_s(_1, _2); } // CHECK-LABEL: @xvfcvt_s_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvt.s.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvt.s.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfcvt_s_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcvt_s_d(_1, _2); } // CHECK-LABEL: @xvfmin_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmin.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmin.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmin_s(v8f32 _1, v8f32 _2) { return __lasx_xvfmin_s(_1, _2); } // CHECK-LABEL: @xvfmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmin.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmin.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmin_d(v4f64 _1, v4f64 _2) { return __lasx_xvfmin_d(_1, _2); } // CHECK-LABEL: @xvfmina_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmina.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmina.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmina_s(v8f32 _1, v8f32 _2) { return __lasx_xvfmina_s(_1, _2); } // CHECK-LABEL: @xvfmina_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmina.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmina.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmina_d(v4f64 _1, v4f64 _2) { return __lasx_xvfmina_d(_1, _2); } // CHECK-LABEL: @xvfmax_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmax.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmax.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmax_s(v8f32 _1, v8f32 _2) { return __lasx_xvfmax_s(_1, _2); } // CHECK-LABEL: @xvfmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmax.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmax.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmax_d(v4f64 _1, v4f64 _2) { return __lasx_xvfmax_d(_1, _2); } // CHECK-LABEL: @xvfmaxa_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmaxa.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmaxa.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmaxa_s(v8f32 _1, v8f32 _2) { return __lasx_xvfmaxa_s(_1, _2); } // CHECK-LABEL: @xvfmaxa_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmaxa.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmaxa.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmaxa_d(v4f64 _1, v4f64 _2) { return __lasx_xvfmaxa_d(_1, _2); } // CHECK-LABEL: @xvfclass_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfclass.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfclass.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfclass_s(v8f32 _1) { return __lasx_xvfclass_s(_1); } // CHECK-LABEL: @xvfclass_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfclass.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfclass.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfclass_d(v4f64 _1) { return __lasx_xvfclass_d(_1); } // CHECK-LABEL: @xvfsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsqrt.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsqrt.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfsqrt_s(v8f32 _1) { return __lasx_xvfsqrt_s(_1); } // CHECK-LABEL: @xvfsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsqrt.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsqrt.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfsqrt_d(v4f64 _1) { return __lasx_xvfsqrt_d(_1); } // CHECK-LABEL: @xvfrecip_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrecip.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrecip.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfrecip_s(v8f32 _1) { return __lasx_xvfrecip_s(_1); } // CHECK-LABEL: @xvfrecip_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrecip.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrecip.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfrecip_d(v4f64 _1) { return __lasx_xvfrecip_d(_1); } // CHECK-LABEL: @xvfrint_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrint.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrint.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfrint_s(v8f32 _1) { return __lasx_xvfrint_s(_1); } // CHECK-LABEL: @xvfrint_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrint.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrint.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfrint_d(v4f64 _1) { return __lasx_xvfrint_d(_1); } // CHECK-LABEL: @xvfrsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrsqrt.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrsqrt.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfrsqrt_s(v8f32 _1) { return __lasx_xvfrsqrt_s(_1); } // CHECK-LABEL: @xvfrsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrsqrt.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrsqrt.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfrsqrt_d(v4f64 _1) { return __lasx_xvfrsqrt_d(_1); } // CHECK-LABEL: @xvflogb_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvflogb.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvflogb.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvflogb_s(v8f32 _1) { return __lasx_xvflogb_s(_1); } // CHECK-LABEL: @xvflogb_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvflogb.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvflogb.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvflogb_d(v4f64 _1) { return __lasx_xvflogb_d(_1); } // CHECK-LABEL: @xvfcvth_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvth.s.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvth.s.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfcvth_s_h(v16i16 _1) { return __lasx_xvfcvth_s_h(_1); } // CHECK-LABEL: @xvfcvth_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvth.d.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvth.d.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfcvth_d_s(v8f32 _1) { return __lasx_xvfcvth_d_s(_1); } // CHECK-LABEL: @xvfcvtl_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvtl.s.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvtl.s.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfcvtl_s_h(v16i16 _1) { return __lasx_xvfcvtl_s_h(_1); } // CHECK-LABEL: @xvfcvtl_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvtl.d.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvtl.d.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfcvtl_d_s(v8f32 _1) { return __lasx_xvfcvtl_d_s(_1); } // CHECK-LABEL: @xvftint_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftint_w_s(v8f32 _1) { return __lasx_xvftint_w_s(_1); } // CHECK-LABEL: @xvftint_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftint_l_d(v4f64 _1) { return __lasx_xvftint_l_d(_1); } // CHECK-LABEL: @xvftint_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.wu.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.wu.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvftint_wu_s(v8f32 _1) { return __lasx_xvftint_wu_s(_1); } // CHECK-LABEL: @xvftint_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.lu.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.lu.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvftint_lu_d(v4f64 _1) { return __lasx_xvftint_lu_d(_1); } // CHECK-LABEL: @xvftintrz_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrz_w_s(v8f32 _1) { return __lasx_xvftintrz_w_s(_1); } // CHECK-LABEL: @xvftintrz_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrz_l_d(v4f64 _1) { return __lasx_xvftintrz_l_d(_1); } // CHECK-LABEL: @xvftintrz_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.wu.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.wu.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvftintrz_wu_s(v8f32 _1) { return __lasx_xvftintrz_wu_s(_1); } // CHECK-LABEL: @xvftintrz_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.lu.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.lu.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvftintrz_lu_d(v4f64 _1) { return __lasx_xvftintrz_lu_d(_1); } // CHECK-LABEL: @xvffint_s_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvffint_s_w(v8i32 _1) { return __lasx_xvffint_s_w(_1); } // CHECK-LABEL: @xvffint_d_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.l(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.l(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffint_d_l(v4i64 _1) { return __lasx_xvffint_d_l(_1); } // CHECK-LABEL: @xvffint_s_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.wu(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.wu(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvffint_s_wu(v8u32 _1) { return __lasx_xvffint_s_wu(_1); } // CHECK-LABEL: @xvffint_d_lu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.lu(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.lu(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffint_d_lu(v4u64 _1) { return __lasx_xvffint_d_lu(_1); } // CHECK-LABEL: @xvreplve_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve.b(<32 x i8> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve.b(<32 x i8> [[_112]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplve_b(v32i8 _1, int _2) { return __lasx_xvreplve_b(_1, _2); } // CHECK-LABEL: @xvreplve_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve.h(<16 x i16> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve.h(<16 x i16> [[_112]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvreplve_h(v16i16 _1, int _2) { return __lasx_xvreplve_h(_1, _2); } // CHECK-LABEL: @xvreplve_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve.w(<8 x i32> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve.w(<8 x i32> [[_112]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvreplve_w(v8i32 _1, int _2) { return __lasx_xvreplve_w(_1, _2); } // CHECK-LABEL: @xvreplve_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve.d(<4 x i64> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve.d(<4 x i64> [[_1]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvreplve_d(v4i64 _1, int _2) { return __lasx_xvreplve_d(_1, _2); } // CHECK-LABEL: @xvpermi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpermi_w(v8i32 _1, v8i32 _2) { return __lasx_xvpermi_w(_1, _2, 1); } // CHECK-LABEL: @xvandn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandn.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandn.v(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvandn_v(v32u8 _1, v32u8 _2) { return __lasx_xvandn_v(_1, _2); } // CHECK-LABEL: @xvneg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvneg.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvneg.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvneg_b(v32i8 _1) { return __lasx_xvneg_b(_1); } // CHECK-LABEL: @xvneg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvneg.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvneg.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvneg_h(v16i16 _1) { return __lasx_xvneg_h(_1); } // CHECK-LABEL: @xvneg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvneg.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvneg.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvneg_w(v8i32 _1) { return __lasx_xvneg_w(_1); } // CHECK-LABEL: @xvneg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvneg.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvneg.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvneg_d(v4i64 _1) { return __lasx_xvneg_d(_1); } // CHECK-LABEL: @xvmuh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmuh_b(v32i8 _1, v32i8 _2) { return __lasx_xvmuh_b(_1, _2); } // CHECK-LABEL: @xvmuh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmuh_h(v16i16 _1, v16i16 _2) { return __lasx_xvmuh_h(_1, _2); } // CHECK-LABEL: @xvmuh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmuh_w(v8i32 _1, v8i32 _2) { return __lasx_xvmuh_w(_1, _2); } // CHECK-LABEL: @xvmuh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmuh_d(v4i64 _1, v4i64 _2) { return __lasx_xvmuh_d(_1, _2); } // CHECK-LABEL: @xvmuh_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmuh_bu(v32u8 _1, v32u8 _2) { return __lasx_xvmuh_bu(_1, _2); } // CHECK-LABEL: @xvmuh_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmuh_hu(v16u16 _1, v16u16 _2) { return __lasx_xvmuh_hu(_1, _2); } // CHECK-LABEL: @xvmuh_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmuh_wu(v8u32 _1, v8u32 _2) { return __lasx_xvmuh_wu(_1, _2); } // CHECK-LABEL: @xvmuh_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmuh_du(v4u64 _1, v4u64 _2) { return __lasx_xvmuh_du(_1, _2); } // CHECK-LABEL: @xvsllwil_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsllwil_h_b(v32i8 _1) { return __lasx_xvsllwil_h_b(_1, 1); } // CHECK-LABEL: @xvsllwil_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsllwil_w_h(v16i16 _1) { return __lasx_xvsllwil_w_h(_1, 1); } // CHECK-LABEL: @xvsllwil_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsllwil_d_w(v8i32 _1) { return __lasx_xvsllwil_d_w(_1, 1); } // CHECK-LABEL: @xvsllwil_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvsllwil_hu_bu(v32u8 _1) { return __lasx_xvsllwil_hu_bu(_1, 1); } // CHECK-LABEL: @xvsllwil_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvsllwil_wu_hu(v16u16 _1) { return __lasx_xvsllwil_wu_hu(_1, 1); } // CHECK-LABEL: @xvsllwil_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvsllwil_du_wu(v8u32 _1) { return __lasx_xvsllwil_du_wu(_1, 1); } // CHECK-LABEL: @xvsran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsran.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsran.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsran_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvsran_b_h(_1, _2); } // CHECK-LABEL: @xvsran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsran.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsran.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsran_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvsran_h_w(_1, _2); } // CHECK-LABEL: @xvsran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsran.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsran.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsran_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvsran_w_d(_1, _2); } // CHECK-LABEL: @xvssran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssran_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvssran_b_h(_1, _2); } // CHECK-LABEL: @xvssran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssran_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvssran_h_w(_1, _2); } // CHECK-LABEL: @xvssran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssran_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvssran_w_d(_1, _2); } // CHECK-LABEL: @xvssran_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.bu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssran_bu_h(v16u16 _1, v16u16 _2) { return __lasx_xvssran_bu_h(_1, _2); } // CHECK-LABEL: @xvssran_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.hu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssran_hu_w(v8u32 _1, v8u32 _2) { return __lasx_xvssran_hu_w(_1, _2); } // CHECK-LABEL: @xvssran_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssran_wu_d(v4u64 _1, v4u64 _2) { return __lasx_xvssran_wu_d(_1, _2); } // CHECK-LABEL: @xvsrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarn.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrarn_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvsrarn_b_h(_1, _2); } // CHECK-LABEL: @xvsrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarn.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrarn_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvsrarn_h_w(_1, _2); } // CHECK-LABEL: @xvsrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrarn_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvsrarn_w_d(_1, _2); } // CHECK-LABEL: @xvssrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrarn_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvssrarn_b_h(_1, _2); } // CHECK-LABEL: @xvssrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrarn_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvssrarn_h_w(_1, _2); } // CHECK-LABEL: @xvssrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrarn_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvssrarn_w_d(_1, _2); } // CHECK-LABEL: @xvssrarn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.bu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrarn_bu_h(v16u16 _1, v16u16 _2) { return __lasx_xvssrarn_bu_h(_1, _2); } // CHECK-LABEL: @xvssrarn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.hu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrarn_hu_w(v8u32 _1, v8u32 _2) { return __lasx_xvssrarn_hu_w(_1, _2); } // CHECK-LABEL: @xvssrarn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrarn_wu_d(v4u64 _1, v4u64 _2) { return __lasx_xvssrarn_wu_d(_1, _2); } // CHECK-LABEL: @xvsrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrln.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrln.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrln_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvsrln_b_h(_1, _2); } // CHECK-LABEL: @xvsrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrln.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrln.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrln_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvsrln_h_w(_1, _2); } // CHECK-LABEL: @xvsrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrln.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrln.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrln_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvsrln_w_d(_1, _2); } // CHECK-LABEL: @xvssrln_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.bu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrln_bu_h(v16u16 _1, v16u16 _2) { return __lasx_xvssrln_bu_h(_1, _2); } // CHECK-LABEL: @xvssrln_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.hu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrln_hu_w(v8u32 _1, v8u32 _2) { return __lasx_xvssrln_hu_w(_1, _2); } // CHECK-LABEL: @xvssrln_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrln_wu_d(v4u64 _1, v4u64 _2) { return __lasx_xvssrln_wu_d(_1, _2); } // CHECK-LABEL: @xvsrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrn.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlrn_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvsrlrn_b_h(_1, _2); } // CHECK-LABEL: @xvsrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrn.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlrn_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvsrlrn_h_w(_1, _2); } // CHECK-LABEL: @xvsrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlrn_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvsrlrn_w_d(_1, _2); } // CHECK-LABEL: @xvssrlrn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.bu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrlrn_bu_h(v16u16 _1, v16u16 _2) { return __lasx_xvssrlrn_bu_h(_1, _2); } // CHECK-LABEL: @xvssrlrn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.hu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrlrn_hu_w(v8u32 _1, v8u32 _2) { return __lasx_xvssrlrn_hu_w(_1, _2); } // CHECK-LABEL: @xvssrlrn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrlrn_wu_d(v4u64 _1, v4u64 _2) { return __lasx_xvssrlrn_wu_d(_1, _2); } // CHECK-LABEL: @xvfrstpi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvfrstpi_b(v32i8 _1, v32i8 _2) { return __lasx_xvfrstpi_b(_1, _2, 1); } // CHECK-LABEL: @xvfrstpi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvfrstpi_h(v16i16 _1, v16i16 _2) { return __lasx_xvfrstpi_h(_1, _2, 1); } // CHECK-LABEL: @xvfrstp_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstp.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstp.b(<32 x i8> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvfrstp_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __lasx_xvfrstp_b(_1, _2, _3); } // CHECK-LABEL: @xvfrstp_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstp.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstp.h(<16 x i16> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvfrstp_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __lasx_xvfrstp_h(_1, _2, _3); } // CHECK-LABEL: @xvshuf4i_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvshuf4i_d(v4i64 _1, v4i64 _2) { return __lasx_xvshuf4i_d(_1, _2, 1); } // CHECK-LABEL: @xvbsrl_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvbsrl_v(v32i8 _1) { return __lasx_xvbsrl_v(_1, 1); } // CHECK-LABEL: @xvbsll_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvbsll_v(v32i8 _1) { return __lasx_xvbsll_v(_1, 1); } // CHECK-LABEL: @xvextrins_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvextrins_b(v32i8 _1, v32i8 _2) { return __lasx_xvextrins_b(_1, _2, 1); } // CHECK-LABEL: @xvextrins_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvextrins_h(v16i16 _1, v16i16 _2) { return __lasx_xvextrins_h(_1, _2, 1); } // CHECK-LABEL: @xvextrins_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvextrins_w(v8i32 _1, v8i32 _2) { return __lasx_xvextrins_w(_1, _2, 1); } // CHECK-LABEL: @xvextrins_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvextrins_d(v4i64 _1, v4i64 _2) { return __lasx_xvextrins_d(_1, _2, 1); } // CHECK-LABEL: @xvmskltz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskltz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskltz.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmskltz_b(v32i8 _1) { return __lasx_xvmskltz_b(_1); } // CHECK-LABEL: @xvmskltz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmskltz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmskltz.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmskltz_h(v16i16 _1) { return __lasx_xvmskltz_h(_1); } // CHECK-LABEL: @xvmskltz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmskltz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmskltz.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmskltz_w(v8i32 _1) { return __lasx_xvmskltz_w(_1); } // CHECK-LABEL: @xvmskltz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmskltz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmskltz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmskltz_d(v4i64 _1) { return __lasx_xvmskltz_d(_1); } // CHECK-LABEL: @xvsigncov_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsigncov.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsigncov.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsigncov_b(v32i8 _1, v32i8 _2) { return __lasx_xvsigncov_b(_1, _2); } // CHECK-LABEL: @xvsigncov_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsigncov.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsigncov.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsigncov_h(v16i16 _1, v16i16 _2) { return __lasx_xvsigncov_h(_1, _2); } // CHECK-LABEL: @xvsigncov_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsigncov.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsigncov.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsigncov_w(v8i32 _1, v8i32 _2) { return __lasx_xvsigncov_w(_1, _2); } // CHECK-LABEL: @xvsigncov_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsigncov.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsigncov.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsigncov_d(v4i64 _1, v4i64 _2) { return __lasx_xvsigncov_d(_1, _2); } // CHECK-LABEL: @xvfmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmadd.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmadd.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmadd_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __lasx_xvfmadd_s(_1, _2, _3); } // CHECK-LABEL: @xvfmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmadd.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmadd.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmadd_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __lasx_xvfmadd_d(_1, _2, _3); } // CHECK-LABEL: @xvfmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmsub.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmsub.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmsub_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __lasx_xvfmsub_s(_1, _2, _3); } // CHECK-LABEL: @xvfmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmsub.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmsub.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmsub_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __lasx_xvfmsub_d(_1, _2, _3); } // CHECK-LABEL: @xvfnmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmadd.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmadd.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfnmadd_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __lasx_xvfnmadd_s(_1, _2, _3); } // CHECK-LABEL: @xvfnmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmadd.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmadd.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfnmadd_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __lasx_xvfnmadd_d(_1, _2, _3); } // CHECK-LABEL: @xvfnmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmsub.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmsub.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfnmsub_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __lasx_xvfnmsub_s(_1, _2, _3); } // CHECK-LABEL: @xvfnmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmsub.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmsub.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfnmsub_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __lasx_xvfnmsub_d(_1, _2, _3); } // CHECK-LABEL: @xvftintrne_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrne_w_s(v8f32 _1) { return __lasx_xvftintrne_w_s(_1); } // CHECK-LABEL: @xvftintrne_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrne.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrne.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrne_l_d(v4f64 _1) { return __lasx_xvftintrne_l_d(_1); } // CHECK-LABEL: @xvftintrp_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrp_w_s(v8f32 _1) { return __lasx_xvftintrp_w_s(_1); } // CHECK-LABEL: @xvftintrp_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrp.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrp.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrp_l_d(v4f64 _1) { return __lasx_xvftintrp_l_d(_1); } // CHECK-LABEL: @xvftintrm_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrm_w_s(v8f32 _1) { return __lasx_xvftintrm_w_s(_1); } // CHECK-LABEL: @xvftintrm_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrm.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrm.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrm_l_d(v4f64 _1) { return __lasx_xvftintrm_l_d(_1); } // CHECK-LABEL: @xvftint_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftint_w_d(v4f64 _1, v4f64 _2) { return __lasx_xvftint_w_d(_1, _2); } // CHECK-LABEL: @xvffint_s_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.l(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.l(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvffint_s_l(v4i64 _1, v4i64 _2) { return __lasx_xvffint_s_l(_1, _2); } // CHECK-LABEL: @xvftintrz_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrz_w_d(v4f64 _1, v4f64 _2) { return __lasx_xvftintrz_w_d(_1, _2); } // CHECK-LABEL: @xvftintrp_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrp_w_d(v4f64 _1, v4f64 _2) { return __lasx_xvftintrp_w_d(_1, _2); } // CHECK-LABEL: @xvftintrm_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrm_w_d(v4f64 _1, v4f64 _2) { return __lasx_xvftintrm_w_d(_1, _2); } // CHECK-LABEL: @xvftintrne_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrne_w_d(v4f64 _1, v4f64 _2) { return __lasx_xvftintrne_w_d(_1, _2); } // CHECK-LABEL: @xvftinth_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftinth.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftinth.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftinth_l_s(v8f32 _1) { return __lasx_xvftinth_l_s(_1); } // CHECK-LABEL: @xvftintl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintl.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintl.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintl_l_s(v8f32 _1) { return __lasx_xvftintl_l_s(_1); } // CHECK-LABEL: @xvffinth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffinth.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffinth.d.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffinth_d_w(v8i32 _1) { return __lasx_xvffinth_d_w(_1); } // CHECK-LABEL: @xvffintl_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffintl.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffintl.d.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffintl_d_w(v8i32 _1) { return __lasx_xvffintl_d_w(_1); } // CHECK-LABEL: @xvftintrzh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzh.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzh.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrzh_l_s(v8f32 _1) { return __lasx_xvftintrzh_l_s(_1); } // CHECK-LABEL: @xvftintrzl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzl.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzl.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrzl_l_s(v8f32 _1) { return __lasx_xvftintrzl_l_s(_1); } // CHECK-LABEL: @xvftintrph_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrph.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrph.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrph_l_s(v8f32 _1) { return __lasx_xvftintrph_l_s(_1); } // CHECK-LABEL: @xvftintrpl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrpl.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrpl.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrpl_l_s(v8f32 _1) { return __lasx_xvftintrpl_l_s(_1); } // CHECK-LABEL: @xvftintrmh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrmh.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrmh.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrmh_l_s(v8f32 _1) { return __lasx_xvftintrmh_l_s(_1); } // CHECK-LABEL: @xvftintrml_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrml.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrml.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrml_l_s(v8f32 _1) { return __lasx_xvftintrml_l_s(_1); } // CHECK-LABEL: @xvftintrneh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrneh.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrneh.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrneh_l_s(v8f32 _1) { return __lasx_xvftintrneh_l_s(_1); } // CHECK-LABEL: @xvftintrnel_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrnel.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrnel.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrnel_l_s(v8f32 _1) { return __lasx_xvftintrnel_l_s(_1); } // CHECK-LABEL: @xvfrintrne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrne.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrne.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrne_s(v8f32 _1) { return __lasx_xvfrintrne_s(_1); } // CHECK-LABEL: @xvfrintrne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrne.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrne.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrne_d(v4f64 _1) { return __lasx_xvfrintrne_d(_1); } // CHECK-LABEL: @xvfrintrz_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrz.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrz.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrz_s(v8f32 _1) { return __lasx_xvfrintrz_s(_1); } // CHECK-LABEL: @xvfrintrz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrz.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrz.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrz_d(v4f64 _1) { return __lasx_xvfrintrz_d(_1); } // CHECK-LABEL: @xvfrintrp_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrp.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrp.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrp_s(v8f32 _1) { return __lasx_xvfrintrp_s(_1); } // CHECK-LABEL: @xvfrintrp_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrp.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrp.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrp_d(v4f64 _1) { return __lasx_xvfrintrp_d(_1); } // CHECK-LABEL: @xvfrintrm_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrm.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrm.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrm_s(v8f32 _1) { return __lasx_xvfrintrm_s(_1); } // CHECK-LABEL: @xvfrintrm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrm.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrm.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrm_d(v4f64 _1) { return __lasx_xvfrintrm_d(_1); } // CHECK-LABEL: @xvld( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvld(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvld(void * _1) { return __lasx_xvld(_1, 1); } // CHECK-LABEL: @xvst( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvst(<32 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvst(<32 x i8> [[_1]], ptr [[_2:%.*]], i32 1) // CHECK-NEXT: ret void // void xvst(v32i8 _1, void * _2) { return __lasx_xvst(_1, _2, 1); } // CHECK-LABEL: @xvstelm_b( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> [[_1]], ptr [[_2:%.*]], i32 1, i32 1) // CHECK-NEXT: ret void // void xvstelm_b(v32i8 _1, void * _2) { return __lasx_xvstelm_b(_1, _2, 1, 1); } // CHECK-LABEL: @xvstelm_h( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> [[_1:%.*]], ptr [[_2:%.*]], i32 2, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> [[_1]], ptr [[_2:%.*]], i32 2, i32 1) // CHECK-NEXT: ret void // void xvstelm_h(v16i16 _1, void * _2) { return __lasx_xvstelm_h(_1, _2, 2, 1); } // CHECK-LABEL: @xvstelm_w( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> [[_1:%.*]], ptr [[_2:%.*]], i32 4, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> [[_1]], ptr [[_2:%.*]], i32 4, i32 1) // CHECK-NEXT: ret void // void xvstelm_w(v8i32 _1, void * _2) { return __lasx_xvstelm_w(_1, _2, 4, 1); } // CHECK-LABEL: @xvstelm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> [[_1:%.*]], ptr [[_2:%.*]], i32 8, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> [[_1]], ptr [[_2:%.*]], i32 8, i32 1) // CHECK-NEXT: ret void // void xvstelm_d(v4i64 _1, void * _2) { return __lasx_xvstelm_d(_1, _2, 8, 1); } // CHECK-LABEL: @xvinsve0_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvinsve0_w(v8i32 _1, v8i32 _2) { return __lasx_xvinsve0_w(_1, _2, 1); } // CHECK-LABEL: @xvinsve0_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvinsve0_d(v4i64 _1, v4i64 _2) { return __lasx_xvinsve0_d(_1, _2, 1); } // CHECK-LABEL: @xvpickve_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpickve_w(v8i32 _1) { return __lasx_xvpickve_w(_1, 1); } // CHECK-LABEL: @xvpickve_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpickve_d(v4i64 _1) { return __lasx_xvpickve_d(_1, 1); } // CHECK-LABEL: @xvssrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrlrn_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvssrlrn_b_h(_1, _2); } // CHECK-LABEL: @xvssrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrlrn_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvssrlrn_h_w(_1, _2); } // CHECK-LABEL: @xvssrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrlrn_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvssrlrn_w_d(_1, _2); } // CHECK-LABEL: @xvssrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.b.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrln_b_h(v16i16 _1, v16i16 _2) { return __lasx_xvssrln_b_h(_1, _2); } // CHECK-LABEL: @xvssrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.h.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrln_h_w(v8i32 _1, v8i32 _2) { return __lasx_xvssrln_h_w(_1, _2); } // CHECK-LABEL: @xvssrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrln_w_d(v4i64 _1, v4i64 _2) { return __lasx_xvssrln_w_d(_1, _2); } // CHECK-LABEL: @xvorn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvorn.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvorn.v(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvorn_v(v32i8 _1, v32i8 _2) { return __lasx_xvorn_v(_1, _2); } // CHECK-LABEL: @xvldi( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvldi(i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvldi() { return __lasx_xvldi(1); } // CHECK-LABEL: @xvldx( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvldx(ptr [[_1:%.*]], i64 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvldx(ptr [[_1:%.*]], i64 1), !noalias [[META5:![0-9]+]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvldx(void * _1) { return __lasx_xvldx(_1, 1); } // CHECK-LABEL: @xvstx( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstx(<32 x i8> [[_1:%.*]], ptr [[_2:%.*]], i64 1) +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstx(<32 x i8> [[_112]], ptr [[_2:%.*]], i64 1) // CHECK-NEXT: ret void // void xvstx(v32i8 _1, void * _2) { return __lasx_xvstx(_1, _2, 1); } // CHECK-LABEL: @xvextl_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.qu.du(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.qu.du(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvextl_qu_du(v4u64 _1) { return __lasx_xvextl_qu_du(_1); } // CHECK-LABEL: @xvinsgr2vr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> [[_1]], i32 1, i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvinsgr2vr_w(v8i32 _1) { return __lasx_xvinsgr2vr_w(_1, 1, 1); } // CHECK-LABEL: @xvinsgr2vr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> [[_1:%.*]], i64 1, i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> [[_1]], i64 1, i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvinsgr2vr_d(v4i64 _1) { return __lasx_xvinsgr2vr_d(_1, 1, 1); } // CHECK-LABEL: @xvreplve0_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplve0_b(v32i8 _1) { return __lasx_xvreplve0_b(_1); } // CHECK-LABEL: @xvreplve0_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve0.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve0.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvreplve0_h(v16i16 _1) { return __lasx_xvreplve0_h(_1); } // CHECK-LABEL: @xvreplve0_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve0.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve0.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvreplve0_w(v8i32 _1) { return __lasx_xvreplve0_w(_1); } // CHECK-LABEL: @xvreplve0_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve0.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve0.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvreplve0_d(v4i64 _1) { return __lasx_xvreplve0_d(_1); } // CHECK-LABEL: @xvreplve0_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.q(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.q(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplve0_q(v32i8 _1) { return __lasx_xvreplve0_q(_1); } // CHECK-LABEL: @vext2xv_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.h.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.h.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 vext2xv_h_b(v32i8 _1) { return __lasx_vext2xv_h_b(_1); } // CHECK-LABEL: @vext2xv_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_w_h(v16i16 _1) { return __lasx_vext2xv_w_h(_1); } // CHECK-LABEL: @vext2xv_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_d_w(v8i32 _1) { return __lasx_vext2xv_d_w(_1); } // CHECK-LABEL: @vext2xv_w_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_w_b(v32i8 _1) { return __lasx_vext2xv_w_b(_1); } // CHECK-LABEL: @vext2xv_d_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_d_h(v16i16 _1) { return __lasx_vext2xv_d_h(_1); } // CHECK-LABEL: @vext2xv_d_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_d_b(v32i8 _1) { return __lasx_vext2xv_d_b(_1); } // CHECK-LABEL: @vext2xv_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.hu.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.hu.bu(<32 x i8> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 vext2xv_hu_bu(v32i8 _1) { return __lasx_vext2xv_hu_bu(_1); } // CHECK-LABEL: @vext2xv_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.hu(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.hu(<16 x i16> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_wu_hu(v16i16 _1) { return __lasx_vext2xv_wu_hu(_1); } // CHECK-LABEL: @vext2xv_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.wu(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.wu(<8 x i32> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_du_wu(v8i32 _1) { return __lasx_vext2xv_du_wu(_1); } // CHECK-LABEL: @vext2xv_wu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.bu(<32 x i8> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_wu_bu(v32i8 _1) { return __lasx_vext2xv_wu_bu(_1); } // CHECK-LABEL: @vext2xv_du_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.hu(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.hu(<16 x i16> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_du_hu(v16i16 _1) { return __lasx_vext2xv_du_hu(_1); } // CHECK-LABEL: @vext2xv_du_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.bu(<32 x i8> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_du_bu(v32i8 _1) { return __lasx_vext2xv_du_bu(_1); } // CHECK-LABEL: @xvpermi_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpermi_q(v32i8 _1, v32i8 _2) { return __lasx_xvpermi_q(_1, _2, 1); } // CHECK-LABEL: @xvpermi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpermi_d(v4i64 _1) { return __lasx_xvpermi_d(_1, 1); } // CHECK-LABEL: @xvperm_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvperm.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvperm.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvperm_w(v8i32 _1, v8i32 _2) { return __lasx_xvperm_w(_1, _2); } // CHECK-LABEL: @xvldrepl_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvldrepl_b(void * _1) { return __lasx_xvldrepl_b(_1, 1); } // CHECK-LABEL: @xvldrepl_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(ptr [[_1:%.*]], i32 2) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: store <16 x i16> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvldrepl_h(void * _1) { return __lasx_xvldrepl_h(_1, 2); } // CHECK-LABEL: @xvldrepl_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(ptr [[_1:%.*]], i32 4) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: store <8 x i32> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvldrepl_w(void * _1) { return __lasx_xvldrepl_w(_1, 4); } // CHECK-LABEL: @xvldrepl_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(ptr [[_1:%.*]], i32 8) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvldrepl_d(void * _1) { return __lasx_xvldrepl_d(_1, 8); } // CHECK-LABEL: @xvpickve2gr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int xvpickve2gr_w(v8i32 _1) { return __lasx_xvpickve2gr_w(_1, 1); } // CHECK-LABEL: @xvpickve2gr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int xvpickve2gr_wu(v8i32 _1) { return __lasx_xvpickve2gr_wu(_1, 1); } // CHECK-LABEL: @xvpickve2gr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // long xvpickve2gr_d(v4i64 _1) { return __lasx_xvpickve2gr_d(_1, 1); } // CHECK-LABEL: @xvpickve2gr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // unsigned long int xvpickve2gr_du(v4i64 _1) { return __lasx_xvpickve2gr_du(_1, 1); } // CHECK-LABEL: @xvaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvaddwev_q_d(_1, _2); } // CHECK-LABEL: @xvaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvaddwev_d_w(_1, _2); } // CHECK-LABEL: @xvaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwev_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvaddwev_w_h(_1, _2); } // CHECK-LABEL: @xvaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwev_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvaddwev_h_b(_1, _2); } // CHECK-LABEL: @xvaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_q_du(v4u64 _1, v4u64 _2) { return __lasx_xvaddwev_q_du(_1, _2); } // CHECK-LABEL: @xvaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_d_wu(v8u32 _1, v8u32 _2) { return __lasx_xvaddwev_d_wu(_1, _2); } // CHECK-LABEL: @xvaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwev_w_hu(v16u16 _1, v16u16 _2) { return __lasx_xvaddwev_w_hu(_1, _2); } // CHECK-LABEL: @xvaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwev_h_bu(v32u8 _1, v32u8 _2) { return __lasx_xvaddwev_h_bu(_1, _2); } // CHECK-LABEL: @xvsubwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvsubwev_q_d(_1, _2); } // CHECK-LABEL: @xvsubwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvsubwev_d_w(_1, _2); } // CHECK-LABEL: @xvsubwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwev_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvsubwev_w_h(_1, _2); } // CHECK-LABEL: @xvsubwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwev_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvsubwev_h_b(_1, _2); } // CHECK-LABEL: @xvsubwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_q_du(v4u64 _1, v4u64 _2) { return __lasx_xvsubwev_q_du(_1, _2); } // CHECK-LABEL: @xvsubwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_d_wu(v8u32 _1, v8u32 _2) { return __lasx_xvsubwev_d_wu(_1, _2); } // CHECK-LABEL: @xvsubwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwev_w_hu(v16u16 _1, v16u16 _2) { return __lasx_xvsubwev_w_hu(_1, _2); } // CHECK-LABEL: @xvsubwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwev_h_bu(v32u8 _1, v32u8 _2) { return __lasx_xvsubwev_h_bu(_1, _2); } // CHECK-LABEL: @xvmulwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvmulwev_q_d(_1, _2); } // CHECK-LABEL: @xvmulwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvmulwev_d_w(_1, _2); } // CHECK-LABEL: @xvmulwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwev_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvmulwev_w_h(_1, _2); } // CHECK-LABEL: @xvmulwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwev_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvmulwev_h_b(_1, _2); } // CHECK-LABEL: @xvmulwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_q_du(v4u64 _1, v4u64 _2) { return __lasx_xvmulwev_q_du(_1, _2); } // CHECK-LABEL: @xvmulwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_d_wu(v8u32 _1, v8u32 _2) { return __lasx_xvmulwev_d_wu(_1, _2); } // CHECK-LABEL: @xvmulwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwev_w_hu(v16u16 _1, v16u16 _2) { return __lasx_xvmulwev_w_hu(_1, _2); } // CHECK-LABEL: @xvmulwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwev_h_bu(v32u8 _1, v32u8 _2) { return __lasx_xvmulwev_h_bu(_1, _2); } // CHECK-LABEL: @xvaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvaddwod_q_d(_1, _2); } // CHECK-LABEL: @xvaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvaddwod_d_w(_1, _2); } // CHECK-LABEL: @xvaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwod_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvaddwod_w_h(_1, _2); } // CHECK-LABEL: @xvaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwod_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvaddwod_h_b(_1, _2); } // CHECK-LABEL: @xvaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_q_du(v4u64 _1, v4u64 _2) { return __lasx_xvaddwod_q_du(_1, _2); } // CHECK-LABEL: @xvaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_d_wu(v8u32 _1, v8u32 _2) { return __lasx_xvaddwod_d_wu(_1, _2); } // CHECK-LABEL: @xvaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwod_w_hu(v16u16 _1, v16u16 _2) { return __lasx_xvaddwod_w_hu(_1, _2); } // CHECK-LABEL: @xvaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwod_h_bu(v32u8 _1, v32u8 _2) { return __lasx_xvaddwod_h_bu(_1, _2); } // CHECK-LABEL: @xvsubwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvsubwod_q_d(_1, _2); } // CHECK-LABEL: @xvsubwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvsubwod_d_w(_1, _2); } // CHECK-LABEL: @xvsubwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwod_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvsubwod_w_h(_1, _2); } // CHECK-LABEL: @xvsubwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwod_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvsubwod_h_b(_1, _2); } // CHECK-LABEL: @xvsubwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_q_du(v4u64 _1, v4u64 _2) { return __lasx_xvsubwod_q_du(_1, _2); } // CHECK-LABEL: @xvsubwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_d_wu(v8u32 _1, v8u32 _2) { return __lasx_xvsubwod_d_wu(_1, _2); } // CHECK-LABEL: @xvsubwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwod_w_hu(v16u16 _1, v16u16 _2) { return __lasx_xvsubwod_w_hu(_1, _2); } // CHECK-LABEL: @xvsubwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwod_h_bu(v32u8 _1, v32u8 _2) { return __lasx_xvsubwod_h_bu(_1, _2); } // CHECK-LABEL: @xvmulwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvmulwod_q_d(_1, _2); } // CHECK-LABEL: @xvmulwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_d_w(v8i32 _1, v8i32 _2) { return __lasx_xvmulwod_d_w(_1, _2); } // CHECK-LABEL: @xvmulwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwod_w_h(v16i16 _1, v16i16 _2) { return __lasx_xvmulwod_w_h(_1, _2); } // CHECK-LABEL: @xvmulwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwod_h_b(v32i8 _1, v32i8 _2) { return __lasx_xvmulwod_h_b(_1, _2); } // CHECK-LABEL: @xvmulwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_q_du(v4u64 _1, v4u64 _2) { return __lasx_xvmulwod_q_du(_1, _2); } // CHECK-LABEL: @xvmulwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_d_wu(v8u32 _1, v8u32 _2) { return __lasx_xvmulwod_d_wu(_1, _2); } // CHECK-LABEL: @xvmulwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwod_w_hu(v16u16 _1, v16u16 _2) { return __lasx_xvmulwod_w_hu(_1, _2); } // CHECK-LABEL: @xvmulwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwod_h_bu(v32u8 _1, v32u8 _2) { return __lasx_xvmulwod_h_bu(_1, _2); } // CHECK-LABEL: @xvaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_d_wu_w(v8u32 _1, v8i32 _2) { return __lasx_xvaddwev_d_wu_w(_1, _2); } // CHECK-LABEL: @xvaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwev_w_hu_h(v16u16 _1, v16i16 _2) { return __lasx_xvaddwev_w_hu_h(_1, _2); } // CHECK-LABEL: @xvaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwev_h_bu_b(v32u8 _1, v32i8 _2) { return __lasx_xvaddwev_h_bu_b(_1, _2); } // CHECK-LABEL: @xvmulwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_d_wu_w(v8u32 _1, v8i32 _2) { return __lasx_xvmulwev_d_wu_w(_1, _2); } // CHECK-LABEL: @xvmulwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwev_w_hu_h(v16u16 _1, v16i16 _2) { return __lasx_xvmulwev_w_hu_h(_1, _2); } // CHECK-LABEL: @xvmulwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwev_h_bu_b(v32u8 _1, v32i8 _2) { return __lasx_xvmulwev_h_bu_b(_1, _2); } // CHECK-LABEL: @xvaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_d_wu_w(v8u32 _1, v8i32 _2) { return __lasx_xvaddwod_d_wu_w(_1, _2); } // CHECK-LABEL: @xvaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwod_w_hu_h(v16u16 _1, v16i16 _2) { return __lasx_xvaddwod_w_hu_h(_1, _2); } // CHECK-LABEL: @xvaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwod_h_bu_b(v32u8 _1, v32i8 _2) { return __lasx_xvaddwod_h_bu_b(_1, _2); } // CHECK-LABEL: @xvmulwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_d_wu_w(v8u32 _1, v8i32 _2) { return __lasx_xvmulwod_d_wu_w(_1, _2); } // CHECK-LABEL: @xvmulwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwod_w_hu_h(v16u16 _1, v16i16 _2) { return __lasx_xvmulwod_w_hu_h(_1, _2); } // CHECK-LABEL: @xvmulwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwod_h_bu_b(v32u8 _1, v32i8 _2) { return __lasx_xvmulwod_h_bu_b(_1, _2); } // CHECK-LABEL: @xvhaddw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhaddw_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvhaddw_q_d(_1, _2); } // CHECK-LABEL: @xvhaddw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.qu.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.qu.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvhaddw_qu_du(v4u64 _1, v4u64 _2) { return __lasx_xvhaddw_qu_du(_1, _2); } // CHECK-LABEL: @xvhsubw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhsubw_q_d(v4i64 _1, v4i64 _2) { return __lasx_xvhsubw_q_d(_1, _2); } // CHECK-LABEL: @xvhsubw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.qu.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.qu.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvhsubw_qu_du(v4u64 _1, v4u64 _2) { return __lasx_xvhsubw_qu_du(_1, _2); } // CHECK-LABEL: @xvmaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_q_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __lasx_xvmaddwev_q_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_346:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.w(<4 x i64> [[_1]], <8 x i32> [[_235]], <8 x i32> [[_346]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_d_w(v4i64 _1, v8i32 _2, v8i32 _3) { return __lasx_xvmaddwev_d_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.h(<8 x i32> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwev_w_h(v8i32 _1, v16i16 _2, v16i16 _3) { return __lasx_xvmaddwev_w_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.b(<16 x i16> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwev_h_b(v16i16 _1, v32i8 _2, v32i8 _3) { return __lasx_xvmaddwev_h_b(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwev_q_du(v4u64 _1, v4u64 _2, v4u64 _3) { return __lasx_xvmaddwev_q_du(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_346:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu(<4 x i64> [[_1]], <8 x i32> [[_235]], <8 x i32> [[_346]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwev_d_wu(v4u64 _1, v8u32 _2, v8u32 _3) { return __lasx_xvmaddwev_d_wu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu(<8 x i32> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmaddwev_w_hu(v8u32 _1, v16u16 _2, v16u16 _3) { return __lasx_xvmaddwev_w_hu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu(<16 x i16> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmaddwev_h_bu(v16u16 _1, v32u8 _2, v32u8 _3) { return __lasx_xvmaddwev_h_bu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_q_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __lasx_xvmaddwod_q_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_346:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.w(<4 x i64> [[_1]], <8 x i32> [[_235]], <8 x i32> [[_346]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_d_w(v4i64 _1, v8i32 _2, v8i32 _3) { return __lasx_xvmaddwod_d_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.h(<8 x i32> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwod_w_h(v8i32 _1, v16i16 _2, v16i16 _3) { return __lasx_xvmaddwod_w_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.b(<16 x i16> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwod_h_b(v16i16 _1, v32i8 _2, v32i8 _3) { return __lasx_xvmaddwod_h_b(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwod_q_du(v4u64 _1, v4u64 _2, v4u64 _3) { return __lasx_xvmaddwod_q_du(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_346:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu(<4 x i64> [[_1]], <8 x i32> [[_235]], <8 x i32> [[_346]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwod_d_wu(v4u64 _1, v8u32 _2, v8u32 _3) { return __lasx_xvmaddwod_d_wu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu(<8 x i32> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmaddwod_w_hu(v8u32 _1, v16u16 _2, v16u16 _3) { return __lasx_xvmaddwod_w_hu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu(<16 x i16> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmaddwod_h_bu(v16u16 _1, v32u8 _2, v32u8 _3) { return __lasx_xvmaddwod_h_bu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_q_du_d(v4i64 _1, v4u64 _2, v4i64 _3) { return __lasx_xvmaddwev_q_du_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_346:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu.w(<4 x i64> [[_1]], <8 x i32> [[_235]], <8 x i32> [[_346]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_d_wu_w(v4i64 _1, v8u32 _2, v8i32 _3) { return __lasx_xvmaddwev_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu.h(<8 x i32> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwev_w_hu_h(v8i32 _1, v16u16 _2, v16i16 _3) { return __lasx_xvmaddwev_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu.b(<16 x i16> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwev_h_bu_b(v16i16 _1, v32u8 _2, v32i8 _3) { return __lasx_xvmaddwev_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_q_du_d(v4i64 _1, v4u64 _2, v4i64 _3) { return __lasx_xvmaddwod_q_du_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_346:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu.w(<4 x i64> [[_1]], <8 x i32> [[_235]], <8 x i32> [[_346]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_d_wu_w(v4i64 _1, v8u32 _2, v8i32 _3) { return __lasx_xvmaddwod_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu.h(<8 x i32> [[_136]], <16 x i16> [[_247]], <16 x i16> [[_358]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwod_w_hu_h(v8i32 _1, v16u16 _2, v16i16 _3) { return __lasx_xvmaddwod_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_136:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_247:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_358:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu.b(<16 x i16> [[_136]], <32 x i8> [[_247]], <32 x i8> [[_358]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwod_h_bu_b(v16i16 _1, v32u8 _2, v32i8 _3) { return __lasx_xvmaddwod_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @xvrotr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotr.b(<32 x i8> [[_124]], <32 x i8> [[_235]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrotr_b(v32i8 _1, v32i8 _2) { return __lasx_xvrotr_b(_1, _2); } // CHECK-LABEL: @xvrotr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotr.h(<16 x i16> [[_124]], <16 x i16> [[_235]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrotr_h(v16i16 _1, v16i16 _2) { return __lasx_xvrotr_h(_1, _2); } // CHECK-LABEL: @xvrotr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_124:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_235:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotr.w(<8 x i32> [[_124]], <8 x i32> [[_235]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrotr_w(v8i32 _1, v8i32 _2) { return __lasx_xvrotr_w(_1, _2); } // CHECK-LABEL: @xvrotr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrotr_d(v4i64 _1, v4i64 _2) { return __lasx_xvrotr_d(_1, _2); } // CHECK-LABEL: @xvadd_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.q(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvadd_q(v4i64 _1, v4i64 _2) { return __lasx_xvadd_q(_1, _2); } // CHECK-LABEL: @xvsub_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.q(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsub_q(v4i64 _1, v4i64 _2) { return __lasx_xvsub_q(_1, _2); } // CHECK-LABEL: @xvaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_q_du_d(v4u64 _1, v4i64 _2) { return __lasx_xvaddwev_q_du_d(_1, _2); } // CHECK-LABEL: @xvaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_q_du_d(v4u64 _1, v4i64 _2) { return __lasx_xvaddwod_q_du_d(_1, _2); } // CHECK-LABEL: @xvmulwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_q_du_d(v4u64 _1, v4i64 _2) { return __lasx_xvmulwev_q_du_d(_1, _2); } // CHECK-LABEL: @xvmulwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_q_du_d(v4u64 _1, v4i64 _2) { return __lasx_xvmulwod_q_du_d(_1, _2); } // CHECK-LABEL: @xvmskgez_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskgez.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskgez.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmskgez_b(v32i8 _1) { return __lasx_xvmskgez_b(_1); } // CHECK-LABEL: @xvmsknz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsknz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsknz.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmsknz_b(v32i8 _1) { return __lasx_xvmsknz_b(_1); } // CHECK-LABEL: @xvexth_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.h.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.h.b(<32 x i8> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvexth_h_b(v32i8 _1) { return __lasx_xvexth_h_b(_1); } // CHECK-LABEL: @xvexth_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.w.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.w.h(<16 x i16> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvexth_w_h(v16i16 _1) { return __lasx_xvexth_w_h(_1); } // CHECK-LABEL: @xvexth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.d.w(<8 x i32> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvexth_d_w(v8i32 _1) { return __lasx_xvexth_d_w(_1); } // CHECK-LABEL: @xvexth_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.q.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.q.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvexth_q_d(v4i64 _1) { return __lasx_xvexth_q_d(_1); } // CHECK-LABEL: @xvexth_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.hu.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.hu.bu(<32 x i8> [[_112]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvexth_hu_bu(v32u8 _1) { return __lasx_xvexth_hu_bu(_1); } // CHECK-LABEL: @xvexth_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.wu.hu(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.wu.hu(<16 x i16> [[_112]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvexth_wu_hu(v16u16 _1) { return __lasx_xvexth_wu_hu(_1); } // CHECK-LABEL: @xvexth_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.du.wu(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_112:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.du.wu(<8 x i32> [[_112]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvexth_du_wu(v8u32 _1) { return __lasx_xvexth_du_wu(_1); } // CHECK-LABEL: @xvexth_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.qu.du(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.qu.du(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvexth_qu_du(v4u64 _1) { return __lasx_xvexth_qu_du(_1); } // CHECK-LABEL: @xvrotri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrotri_b(v32i8 _1) { return __lasx_xvrotri_b(_1, 1); } // CHECK-LABEL: @xvrotri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrotri_h(v16i16 _1) { return __lasx_xvrotri_h(_1, 1); } // CHECK-LABEL: @xvrotri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrotri_w(v8i32 _1) { return __lasx_xvrotri_w(_1, 1); } // CHECK-LABEL: @xvrotri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrotri_d(v4i64 _1) { return __lasx_xvrotri_d(_1, 1); } // CHECK-LABEL: @xvextl_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.q.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.q.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvextl_q_d(v4i64 _1) { return __lasx_xvextl_q_d(_1); } // CHECK-LABEL: @xvsrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlni_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvsrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlni_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvsrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlni_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvsrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlni_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvsrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlrni_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvsrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlrni_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvsrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlrni_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvsrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlrni_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvsrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrlni_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvssrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrlni_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvssrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrlni_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvssrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrlni_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvssrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrlni_bu_h(v32u8 _1, v32i8 _2) { return __lasx_xvssrlni_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrlni_hu_w(v16u16 _1, v16i16 _2) { return __lasx_xvssrlni_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrlni_wu_d(v8u32 _1, v8i32 _2) { return __lasx_xvssrlni_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrlni_du_q(v4u64 _1, v4i64 _2) { return __lasx_xvssrlni_du_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrlrni_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvssrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrlrni_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvssrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrlrni_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvssrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrlrni_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvssrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrlrni_bu_h(v32u8 _1, v32i8 _2) { return __lasx_xvssrlrni_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrlrni_hu_w(v16u16 _1, v16i16 _2) { return __lasx_xvssrlrni_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrlrni_wu_d(v8u32 _1, v8i32 _2) { return __lasx_xvssrlrni_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrlrni_du_q(v4u64 _1, v4i64 _2) { return __lasx_xvssrlrni_du_q(_1, _2, 1); } // CHECK-LABEL: @xvsrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrani_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvsrani_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrani_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvsrani_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrani_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvsrani_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrani_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvsrani_d_q(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrarni_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvsrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrarni_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvsrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrarni_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvsrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrarni_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvsrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrani_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvssrani_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrani_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvssrani_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrani_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvssrani_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrani_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvssrani_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrani_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrani_bu_h(v32u8 _1, v32i8 _2) { return __lasx_xvssrani_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrani_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrani_hu_w(v16u16 _1, v16i16 _2) { return __lasx_xvssrani_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrani_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrani_wu_d(v8u32 _1, v8i32 _2) { return __lasx_xvssrani_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrani_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrani_du_q(v4u64 _1, v4i64 _2) { return __lasx_xvssrani_du_q(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrarni_b_h(v32i8 _1, v32i8 _2) { return __lasx_xvssrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrarni_h_w(v16i16 _1, v16i16 _2) { return __lasx_xvssrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrarni_w_d(v8i32 _1, v8i32 _2) { return __lasx_xvssrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrarni_d_q(v4i64 _1, v4i64 _2) { return __lasx_xvssrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrarni_bu_h(v32u8 _1, v32i8 _2) { return __lasx_xvssrarni_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrarni_hu_w(v16u16 _1, v16i16 _2) { return __lasx_xvssrarni_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrarni_wu_d(v8u32 _1, v8i32 _2) { return __lasx_xvssrarni_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrarni_du_q(v4u64 _1, v4i64 _2) { return __lasx_xvssrarni_du_q(_1, _2, 1); } // CHECK-LABEL: @xbnz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_b(v32u8 _1) { return __lasx_xbnz_b(_1); } // CHECK-LABEL: @xbnz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_d(v4u64 _1) { return __lasx_xbnz_d(_1); } // CHECK-LABEL: @xbnz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.h(<16 x i16> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_h(v16u16 _1) { return __lasx_xbnz_h(_1); } // CHECK-LABEL: @xbnz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.v(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.v(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_v(v32u8 _1) { return __lasx_xbnz_v(_1); } // CHECK-LABEL: @xbnz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.w(<8 x i32> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_w(v8u32 _1) { return __lasx_xbnz_w(_1); } // CHECK-LABEL: @xbz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_b(v32u8 _1) { return __lasx_xbz_b(_1); } // CHECK-LABEL: @xbz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_d(v4u64 _1) { return __lasx_xbz_d(_1); } // CHECK-LABEL: @xbz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.h(<16 x i16> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_h(v16u16 _1) { return __lasx_xbz_h(_1); } // CHECK-LABEL: @xbz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.v(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.v(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_v(v32u8 _1) { return __lasx_xbz_v(_1); } // CHECK-LABEL: @xbz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.w(<8 x i32> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_w(v8u32 _1) { return __lasx_xbz_w(_1); } // CHECK-LABEL: @xvfcmp_caf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.caf.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.caf.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_caf_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_caf_d(_1, _2); } // CHECK-LABEL: @xvfcmp_caf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.caf.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.caf.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_caf_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_caf_s(_1, _2); } // CHECK-LABEL: @xvfcmp_ceq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.ceq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.ceq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_ceq_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_ceq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_ceq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.ceq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.ceq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_ceq_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_ceq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cle.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cle.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cle_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cle_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cle.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cle.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cle_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cle_s(_1, _2); } // CHECK-LABEL: @xvfcmp_clt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.clt.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.clt.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_clt_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_clt_d(_1, _2); } // CHECK-LABEL: @xvfcmp_clt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.clt.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.clt.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_clt_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_clt_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cne.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cne.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cne_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cne_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cne.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cne.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cne_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cne_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cor.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cor.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cor_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cor_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cor.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cor.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cor_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cor_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cueq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cueq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cueq_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cueq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cueq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cueq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cueq_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cueq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cule.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cule.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cule_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cule_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cule.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cule.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cule_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cule_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cult.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cult.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cult_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cult_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cult.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cult.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cult_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cult_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cun.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cun.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cun_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cun_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cune.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cune.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cune_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_cune_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cune.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cune.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cune_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cune_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cun.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cun.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cun_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_cun_s(_1, _2); } // CHECK-LABEL: @xvfcmp_saf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.saf.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.saf.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_saf_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_saf_d(_1, _2); } // CHECK-LABEL: @xvfcmp_saf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.saf.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.saf.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_saf_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_saf_s(_1, _2); } // CHECK-LABEL: @xvfcmp_seq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.seq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.seq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_seq_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_seq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_seq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.seq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.seq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_seq_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_seq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sle.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sle.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sle_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sle_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sle.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sle.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sle_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sle_s(_1, _2); } // CHECK-LABEL: @xvfcmp_slt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.slt.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.slt.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_slt_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_slt_d(_1, _2); } // CHECK-LABEL: @xvfcmp_slt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.slt.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.slt.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_slt_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_slt_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sne.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sne.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sne_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sne_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sne.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sne.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sne_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sne_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sor.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sor.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sor_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sor_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sor.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sor.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sor_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sor_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sueq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sueq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sueq_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sueq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sueq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sueq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sueq_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sueq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sule.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sule.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sule_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sule_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sule.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sule.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sule_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sule_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sult.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sult.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sult_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sult_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sult.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sult.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sult_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sult_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sun.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sun.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sun_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sun_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sune.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sune.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sune_d(v4f64 _1, v4f64 _2) { return __lasx_xvfcmp_sune_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sune.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sune.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sune_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sune_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sun.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sun.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sun_s(v8f32 _1, v8f32 _2) { return __lasx_xvfcmp_sun_s(_1, _2); } // CHECK-LABEL: @xvpickve_d_f( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> [[_1]], i32 1) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvpickve_d_f(v4f64 _1) { return __lasx_xvpickve_d_f(_1, 1); } // CHECK-LABEL: @xvpickve_w_f( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> [[_1]], i32 1) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvpickve_w_f(v8f32 _1) { return __lasx_xvpickve_w_f(_1, 1); } // CHECK-LABEL: @xvrepli_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrepli_b() { return __lasx_xvrepli_b(1); } // CHECK-LABEL: @xvrepli_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrepli_d() { return __lasx_xvrepli_d(1); } // CHECK-LABEL: @xvrepli_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: store <16 x i16> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrepli_h() { return __lasx_xvrepli_h(1); } // CHECK-LABEL: @xvrepli_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: store <8 x i32> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrepli_w() { return __lasx_xvrepli_w(1); } diff --git a/clang/test/CodeGen/LoongArch/lasx/builtin.c b/clang/test/CodeGen/LoongArch/lasx/builtin.c index 0185f2004d526584aa36b31ad10ff4b9954125cf..f52a23a5faea7b2b0e07adf48db3c178d1190c68 100644 --- a/clang/test/CodeGen/LoongArch/lasx/builtin.c +++ b/clang/test/CodeGen/LoongArch/lasx/builtin.c @@ -27,4426 +27,6382 @@ typedef double v4f64_d __attribute__((vector_size(32), aligned(8))); // CHECK-LABEL: @xvsll_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsll.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsll.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsll_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsll_b(_1, _2); } // CHECK-LABEL: @xvsll_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsll.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsll.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsll_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsll_h(_1, _2); } // CHECK-LABEL: @xvsll_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsll.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsll.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsll_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsll_w(_1, _2); } // CHECK-LABEL: @xvsll_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsll.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsll.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsll_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsll_d(_1, _2); } // CHECK-LABEL: @xvslli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslli_b(v32i8 _1) { return __builtin_lasx_xvslli_b(_1, 1); } // CHECK-LABEL: @xvslli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslli_h(v16i16 _1) { return __builtin_lasx_xvslli_h(_1, 1); } // CHECK-LABEL: @xvslli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslli_w(v8i32 _1) { return __builtin_lasx_xvslli_w(_1, 1); } // CHECK-LABEL: @xvslli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslli_d(v4i64 _1) { return __builtin_lasx_xvslli_d(_1, 1); } // CHECK-LABEL: @xvsra_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsra.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsra.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsra_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsra_b(_1, _2); } // CHECK-LABEL: @xvsra_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsra.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsra.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsra_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsra_h(_1, _2); } // CHECK-LABEL: @xvsra_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsra.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsra.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsra_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsra_w(_1, _2); } // CHECK-LABEL: @xvsra_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsra.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsra.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsra_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsra_d(_1, _2); } // CHECK-LABEL: @xvsrai_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrai_b(v32i8 _1) { return __builtin_lasx_xvsrai_b(_1, 1); } // CHECK-LABEL: @xvsrai_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrai_h(v16i16 _1) { return __builtin_lasx_xvsrai_h(_1, 1); } // CHECK-LABEL: @xvsrai_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrai_w(v8i32 _1) { return __builtin_lasx_xvsrai_w(_1, 1); } // CHECK-LABEL: @xvsrai_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrai_d(v4i64 _1) { return __builtin_lasx_xvsrai_d(_1, 1); } // CHECK-LABEL: @xvsrar_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrar.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrar.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrar_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrar_b(_1, _2); } // CHECK-LABEL: @xvsrar_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrar.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrar.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrar_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrar_h(_1, _2); } // CHECK-LABEL: @xvsrar_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrar.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrar.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrar_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrar_w(_1, _2); } // CHECK-LABEL: @xvsrar_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrar.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrar.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrar_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrar_d(_1, _2); } // CHECK-LABEL: @xvsrari_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrari_b(v32i8 _1) { return __builtin_lasx_xvsrari_b(_1, 1); } // CHECK-LABEL: @xvsrari_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrari_h(v16i16 _1) { return __builtin_lasx_xvsrari_h(_1, 1); } // CHECK-LABEL: @xvsrari_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrari_w(v8i32 _1) { return __builtin_lasx_xvsrari_w(_1, 1); } // CHECK-LABEL: @xvsrari_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrari_d(v4i64 _1) { return __builtin_lasx_xvsrari_d(_1, 1); } // CHECK-LABEL: @xvsrl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrl.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrl.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrl_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrl_b(_1, _2); } // CHECK-LABEL: @xvsrl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrl.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrl.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrl_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrl_h(_1, _2); } // CHECK-LABEL: @xvsrl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrl.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrl.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrl_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrl_w(_1, _2); } // CHECK-LABEL: @xvsrl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrl.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrl.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrl_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrl_d(_1, _2); } // CHECK-LABEL: @xvsrli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrli_b(v32i8 _1) { return __builtin_lasx_xvsrli_b(_1, 1); } // CHECK-LABEL: @xvsrli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrli_h(v16i16 _1) { return __builtin_lasx_xvsrli_h(_1, 1); } // CHECK-LABEL: @xvsrli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrli_w(v8i32 _1) { return __builtin_lasx_xvsrli_w(_1, 1); } // CHECK-LABEL: @xvsrli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrli_d(v4i64 _1) { return __builtin_lasx_xvsrli_d(_1, 1); } // CHECK-LABEL: @xvsrlr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlr.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlr_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrlr_b(_1, _2); } // CHECK-LABEL: @xvsrlr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlr.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlr_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrlr_h(_1, _2); } // CHECK-LABEL: @xvsrlr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlr.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlr_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrlr_w(_1, _2); } // CHECK-LABEL: @xvsrlr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlr_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrlr_d(_1, _2); } // CHECK-LABEL: @xvsrlri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlri_b(v32i8 _1) { return __builtin_lasx_xvsrlri_b(_1, 1); } // CHECK-LABEL: @xvsrlri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlri_h(v16i16 _1) { return __builtin_lasx_xvsrlri_h(_1, 1); } // CHECK-LABEL: @xvsrlri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlri_w(v8i32 _1) { return __builtin_lasx_xvsrlri_w(_1, 1); } // CHECK-LABEL: @xvsrlri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlri_d(v4i64 _1) { return __builtin_lasx_xvsrlri_d(_1, 1); } // CHECK-LABEL: @xvbitclr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclr.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitclr_b(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvbitclr_b(_1, _2); } // CHECK-LABEL: @xvbitclr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclr.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitclr_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvbitclr_h(_1, _2); } // CHECK-LABEL: @xvbitclr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclr.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitclr_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvbitclr_w(_1, _2); } // CHECK-LABEL: @xvbitclr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitclr_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvbitclr_d(_1, _2); } // CHECK-LABEL: @xvbitclri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitclri_b(v32u8 _1) { return __builtin_lasx_xvbitclri_b(_1, 1); } // CHECK-LABEL: @xvbitclri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitclri_h(v16u16 _1) { return __builtin_lasx_xvbitclri_h(_1, 1); } // CHECK-LABEL: @xvbitclri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitclri_w(v8u32 _1) { return __builtin_lasx_xvbitclri_w(_1, 1); } // CHECK-LABEL: @xvbitclri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitclri_d(v4u64 _1) { return __builtin_lasx_xvbitclri_d(_1, 1); } // CHECK-LABEL: @xvbitset_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitset.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitset.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitset_b(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvbitset_b(_1, _2); } // CHECK-LABEL: @xvbitset_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitset.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitset.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitset_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvbitset_h(_1, _2); } // CHECK-LABEL: @xvbitset_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitset.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitset.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitset_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvbitset_w(_1, _2); } // CHECK-LABEL: @xvbitset_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitset.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitset.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitset_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvbitset_d(_1, _2); } // CHECK-LABEL: @xvbitseti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitseti_b(v32u8 _1) { return __builtin_lasx_xvbitseti_b(_1, 1); } // CHECK-LABEL: @xvbitseti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitseti_h(v16u16 _1) { return __builtin_lasx_xvbitseti_h(_1, 1); } // CHECK-LABEL: @xvbitseti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitseti_w(v8u32 _1) { return __builtin_lasx_xvbitseti_w(_1, 1); } // CHECK-LABEL: @xvbitseti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitseti_d(v4u64 _1) { return __builtin_lasx_xvbitseti_d(_1, 1); } // CHECK-LABEL: @xvbitrev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrev.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrev.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitrev_b(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvbitrev_b(_1, _2); } // CHECK-LABEL: @xvbitrev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrev.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrev.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitrev_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvbitrev_h(_1, _2); } // CHECK-LABEL: @xvbitrev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrev.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrev.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitrev_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvbitrev_w(_1, _2); } // CHECK-LABEL: @xvbitrev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrev.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrev.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitrev_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvbitrev_d(_1, _2); } // CHECK-LABEL: @xvbitrevi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitrevi_b(v32u8 _1) { return __builtin_lasx_xvbitrevi_b(_1, 1); } // CHECK-LABEL: @xvbitrevi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvbitrevi_h(v16u16 _1) { return __builtin_lasx_xvbitrevi_h(_1, 1); } // CHECK-LABEL: @xvbitrevi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvbitrevi_w(v8u32 _1) { return __builtin_lasx_xvbitrevi_w(_1, 1); } // CHECK-LABEL: @xvbitrevi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvbitrevi_d(v4u64 _1) { return __builtin_lasx_xvbitrevi_d(_1, 1); } // CHECK-LABEL: @xvadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadd.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvadd_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvadd_b(_1, _2); } // CHECK-LABEL: @xvadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadd.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvadd_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvadd_h(_1, _2); } // CHECK-LABEL: @xvadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadd.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvadd_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvadd_w(_1, _2); } // CHECK-LABEL: @xvadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvadd_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvadd_d(_1, _2); } // CHECK-LABEL: @xvaddi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvaddi_bu(v32i8 _1) { return __builtin_lasx_xvaddi_bu(_1, 1); } // CHECK-LABEL: @xvaddi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddi_hu(v16i16 _1) { return __builtin_lasx_xvaddi_hu(_1, 1); } // CHECK-LABEL: @xvaddi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddi_wu(v8i32 _1) { return __builtin_lasx_xvaddi_wu(_1, 1); } // CHECK-LABEL: @xvaddi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddi_du(v4i64 _1) { return __builtin_lasx_xvaddi_du(_1, 1); } // CHECK-LABEL: @xvsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsub.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsub.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsub_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsub_b(_1, _2); } // CHECK-LABEL: @xvsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsub.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsub.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsub_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsub_h(_1, _2); } // CHECK-LABEL: @xvsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsub_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsub_w(_1, _2); } // CHECK-LABEL: @xvsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsub_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsub_d(_1, _2); } // CHECK-LABEL: @xvsubi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsubi_bu(v32i8 _1) { return __builtin_lasx_xvsubi_bu(_1, 1); } // CHECK-LABEL: @xvsubi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubi_hu(v16i16 _1) { return __builtin_lasx_xvsubi_hu(_1, 1); } // CHECK-LABEL: @xvsubi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubi_wu(v8i32 _1) { return __builtin_lasx_xvsubi_wu(_1, 1); } // CHECK-LABEL: @xvsubi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubi_du(v4i64 _1) { return __builtin_lasx_xvsubi_du(_1, 1); } // CHECK-LABEL: @xvmax_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmax_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmax_b(_1, _2); } // CHECK-LABEL: @xvmax_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmax_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmax_h(_1, _2); } // CHECK-LABEL: @xvmax_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmax_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmax_w(_1, _2); } // CHECK-LABEL: @xvmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmax_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmax_d(_1, _2); } // CHECK-LABEL: @xvmaxi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmaxi_b(v32i8 _1) { return __builtin_lasx_xvmaxi_b(_1, 1); } // CHECK-LABEL: @xvmaxi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaxi_h(v16i16 _1) { return __builtin_lasx_xvmaxi_h(_1, 1); } // CHECK-LABEL: @xvmaxi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaxi_w(v8i32 _1) { return __builtin_lasx_xvmaxi_w(_1, 1); } // CHECK-LABEL: @xvmaxi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaxi_d(v4i64 _1) { return __builtin_lasx_xvmaxi_d(_1, 1); } // CHECK-LABEL: @xvmax_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmax.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmax_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvmax_bu(_1, _2); } // CHECK-LABEL: @xvmax_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmax.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmax_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvmax_hu(_1, _2); } // CHECK-LABEL: @xvmax_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmax.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmax_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvmax_wu(_1, _2); } // CHECK-LABEL: @xvmax_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmax.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmax_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvmax_du(_1, _2); } // CHECK-LABEL: @xvmaxi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmaxi_bu(v32u8 _1) { return __builtin_lasx_xvmaxi_bu(_1, 1); } // CHECK-LABEL: @xvmaxi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmaxi_hu(v16u16 _1) { return __builtin_lasx_xvmaxi_hu(_1, 1); } // CHECK-LABEL: @xvmaxi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmaxi_wu(v8u32 _1) { return __builtin_lasx_xvmaxi_wu(_1, 1); } // CHECK-LABEL: @xvmaxi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaxi_du(v4u64 _1) { return __builtin_lasx_xvmaxi_du(_1, 1); } // CHECK-LABEL: @xvmin_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmin_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmin_b(_1, _2); } // CHECK-LABEL: @xvmin_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmin_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmin_h(_1, _2); } // CHECK-LABEL: @xvmin_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmin_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmin_w(_1, _2); } // CHECK-LABEL: @xvmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmin_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmin_d(_1, _2); } // CHECK-LABEL: @xvmini_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmini_b(v32i8 _1) { return __builtin_lasx_xvmini_b(_1, 1); } // CHECK-LABEL: @xvmini_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmini_h(v16i16 _1) { return __builtin_lasx_xvmini_h(_1, 1); } // CHECK-LABEL: @xvmini_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmini_w(v8i32 _1) { return __builtin_lasx_xvmini_w(_1, 1); } // CHECK-LABEL: @xvmini_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmini_d(v4i64 _1) { return __builtin_lasx_xvmini_d(_1, 1); } // CHECK-LABEL: @xvmin_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmin.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmin_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvmin_bu(_1, _2); } // CHECK-LABEL: @xvmin_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmin.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmin_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvmin_hu(_1, _2); } // CHECK-LABEL: @xvmin_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmin.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmin_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvmin_wu(_1, _2); } // CHECK-LABEL: @xvmin_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmin.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmin_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvmin_du(_1, _2); } // CHECK-LABEL: @xvmini_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmini_bu(v32u8 _1) { return __builtin_lasx_xvmini_bu(_1, 1); } // CHECK-LABEL: @xvmini_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmini_hu(v16u16 _1) { return __builtin_lasx_xvmini_hu(_1, 1); } // CHECK-LABEL: @xvmini_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmini_wu(v8u32 _1) { return __builtin_lasx_xvmini_wu(_1, 1); } // CHECK-LABEL: @xvmini_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmini_du(v4u64 _1) { return __builtin_lasx_xvmini_du(_1, 1); } // CHECK-LABEL: @xvseq_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseq.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseq.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvseq_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvseq_b(_1, _2); } // CHECK-LABEL: @xvseq_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseq.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseq.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvseq_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvseq_h(_1, _2); } // CHECK-LABEL: @xvseq_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseq.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseq.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvseq_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvseq_w(_1, _2); } // CHECK-LABEL: @xvseq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseq.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseq.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvseq_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvseq_d(_1, _2); } // CHECK-LABEL: @xvseqi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvseqi_b(v32i8 _1) { return __builtin_lasx_xvseqi_b(_1, 1); } // CHECK-LABEL: @xvseqi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvseqi_h(v16i16 _1) { return __builtin_lasx_xvseqi_h(_1, 1); } // CHECK-LABEL: @xvseqi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvseqi_w(v8i32 _1) { return __builtin_lasx_xvseqi_w(_1, 1); } // CHECK-LABEL: @xvseqi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvseqi_d(v4i64 _1) { return __builtin_lasx_xvseqi_d(_1, 1); } // CHECK-LABEL: @xvslt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslt_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvslt_b(_1, _2); } // CHECK-LABEL: @xvslt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslt_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvslt_h(_1, _2); } // CHECK-LABEL: @xvslt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslt_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvslt_w(_1, _2); } // CHECK-LABEL: @xvslt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslt_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvslt_d(_1, _2); } // CHECK-LABEL: @xvslti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslti_b(v32i8 _1) { return __builtin_lasx_xvslti_b(_1, 1); } // CHECK-LABEL: @xvslti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslti_h(v16i16 _1) { return __builtin_lasx_xvslti_h(_1, 1); } // CHECK-LABEL: @xvslti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslti_w(v8i32 _1) { return __builtin_lasx_xvslti_w(_1, 1); } // CHECK-LABEL: @xvslti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslti_d(v4i64 _1) { return __builtin_lasx_xvslti_d(_1, 1); } // CHECK-LABEL: @xvslt_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslt.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslt_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvslt_bu(_1, _2); } // CHECK-LABEL: @xvslt_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslt.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslt_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvslt_hu(_1, _2); } // CHECK-LABEL: @xvslt_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslt.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslt_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvslt_wu(_1, _2); } // CHECK-LABEL: @xvslt_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslt.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslt_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvslt_du(_1, _2); } // CHECK-LABEL: @xvslti_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslti_bu(v32u8 _1) { return __builtin_lasx_xvslti_bu(_1, 1); } // CHECK-LABEL: @xvslti_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslti_hu(v16u16 _1) { return __builtin_lasx_xvslti_hu(_1, 1); } // CHECK-LABEL: @xvslti_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslti_wu(v8u32 _1) { return __builtin_lasx_xvslti_wu(_1, 1); } // CHECK-LABEL: @xvslti_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslti_du(v4u64 _1) { return __builtin_lasx_xvslti_du(_1, 1); } // CHECK-LABEL: @xvsle_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsle_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsle_b(_1, _2); } // CHECK-LABEL: @xvsle_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsle_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsle_h(_1, _2); } // CHECK-LABEL: @xvsle_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsle_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsle_w(_1, _2); } // CHECK-LABEL: @xvsle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsle_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsle_d(_1, _2); } // CHECK-LABEL: @xvslei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslei_b(v32i8 _1) { return __builtin_lasx_xvslei_b(_1, 1); } // CHECK-LABEL: @xvslei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslei_h(v16i16 _1) { return __builtin_lasx_xvslei_h(_1, 1); } // CHECK-LABEL: @xvslei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslei_w(v8i32 _1) { return __builtin_lasx_xvslei_w(_1, 1); } // CHECK-LABEL: @xvslei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslei_d(v4i64 _1) { return __builtin_lasx_xvslei_d(_1, 1); } // CHECK-LABEL: @xvsle_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsle.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsle_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvsle_bu(_1, _2); } // CHECK-LABEL: @xvsle_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsle.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsle_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvsle_hu(_1, _2); } // CHECK-LABEL: @xvsle_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsle.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsle_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvsle_wu(_1, _2); } // CHECK-LABEL: @xvsle_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsle.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsle_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvsle_du(_1, _2); } // CHECK-LABEL: @xvslei_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvslei_bu(v32u8 _1) { return __builtin_lasx_xvslei_bu(_1, 1); } // CHECK-LABEL: @xvslei_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvslei_hu(v16u16 _1) { return __builtin_lasx_xvslei_hu(_1, 1); } // CHECK-LABEL: @xvslei_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvslei_wu(v8u32 _1) { return __builtin_lasx_xvslei_wu(_1, 1); } // CHECK-LABEL: @xvslei_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvslei_du(v4u64 _1) { return __builtin_lasx_xvslei_du(_1, 1); } // CHECK-LABEL: @xvsat_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsat_b(v32i8 _1) { return __builtin_lasx_xvsat_b(_1, 1); } // CHECK-LABEL: @xvsat_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsat_h(v16i16 _1) { return __builtin_lasx_xvsat_h(_1, 1); } // CHECK-LABEL: @xvsat_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsat_w(v8i32 _1) { return __builtin_lasx_xvsat_w(_1, 1); } // CHECK-LABEL: @xvsat_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsat_d(v4i64 _1) { return __builtin_lasx_xvsat_d(_1, 1); } // CHECK-LABEL: @xvsat_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvsat_bu(v32u8 _1) { return __builtin_lasx_xvsat_bu(_1, 1); } // CHECK-LABEL: @xvsat_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvsat_hu(v16u16 _1) { return __builtin_lasx_xvsat_hu(_1, 1); } // CHECK-LABEL: @xvsat_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvsat_wu(v8u32 _1) { return __builtin_lasx_xvsat_wu(_1, 1); } // CHECK-LABEL: @xvsat_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvsat_du(v4u64 _1) { return __builtin_lasx_xvsat_du(_1, 1); } // CHECK-LABEL: @xvadda_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadda.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvadda.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvadda_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvadda_b(_1, _2); } // CHECK-LABEL: @xvadda_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadda.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvadda.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvadda_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvadda_h(_1, _2); } // CHECK-LABEL: @xvadda_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadda.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvadda.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvadda_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvadda_w(_1, _2); } // CHECK-LABEL: @xvadda_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadda.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadda.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvadda_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvadda_d(_1, _2); } // CHECK-LABEL: @xvsadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsadd_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsadd_b(_1, _2); } // CHECK-LABEL: @xvsadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsadd_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsadd_h(_1, _2); } // CHECK-LABEL: @xvsadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsadd_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsadd_w(_1, _2); } // CHECK-LABEL: @xvsadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsadd_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsadd_d(_1, _2); } // CHECK-LABEL: @xvsadd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsadd.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvsadd_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvsadd_bu(_1, _2); } // CHECK-LABEL: @xvsadd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsadd.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvsadd_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvsadd_hu(_1, _2); } // CHECK-LABEL: @xvsadd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsadd.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvsadd_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvsadd_wu(_1, _2); } // CHECK-LABEL: @xvsadd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsadd.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvsadd_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvsadd_du(_1, _2); } // CHECK-LABEL: @xvavg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvavg_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvavg_b(_1, _2); } // CHECK-LABEL: @xvavg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvavg_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvavg_h(_1, _2); } // CHECK-LABEL: @xvavg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvavg_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvavg_w(_1, _2); } // CHECK-LABEL: @xvavg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvavg_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvavg_d(_1, _2); } // CHECK-LABEL: @xvavg_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavg.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvavg_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvavg_bu(_1, _2); } // CHECK-LABEL: @xvavg_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavg.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvavg_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvavg_hu(_1, _2); } // CHECK-LABEL: @xvavg_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavg.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvavg_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvavg_wu(_1, _2); } // CHECK-LABEL: @xvavg_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavg.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvavg_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvavg_du(_1, _2); } // CHECK-LABEL: @xvavgr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvavgr_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvavgr_b(_1, _2); } // CHECK-LABEL: @xvavgr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvavgr_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvavgr_h(_1, _2); } // CHECK-LABEL: @xvavgr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvavgr_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvavgr_w(_1, _2); } // CHECK-LABEL: @xvavgr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvavgr_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvavgr_d(_1, _2); } // CHECK-LABEL: @xvavgr_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvavgr.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvavgr_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvavgr_bu(_1, _2); } // CHECK-LABEL: @xvavgr_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvavgr.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvavgr_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvavgr_hu(_1, _2); } // CHECK-LABEL: @xvavgr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvavgr.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvavgr_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvavgr_wu(_1, _2); } // CHECK-LABEL: @xvavgr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvavgr.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvavgr_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvavgr_du(_1, _2); } // CHECK-LABEL: @xvssub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssub_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvssub_b(_1, _2); } // CHECK-LABEL: @xvssub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssub_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssub_h(_1, _2); } // CHECK-LABEL: @xvssub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssub_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssub_w(_1, _2); } // CHECK-LABEL: @xvssub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssub_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssub_d(_1, _2); } // CHECK-LABEL: @xvssub_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssub.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssub_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvssub_bu(_1, _2); } // CHECK-LABEL: @xvssub_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssub.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssub_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvssub_hu(_1, _2); } // CHECK-LABEL: @xvssub_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssub.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssub_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvssub_wu(_1, _2); } // CHECK-LABEL: @xvssub_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssub.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssub_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvssub_du(_1, _2); } // CHECK-LABEL: @xvabsd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvabsd_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvabsd_b(_1, _2); } // CHECK-LABEL: @xvabsd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvabsd_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvabsd_h(_1, _2); } // CHECK-LABEL: @xvabsd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvabsd_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvabsd_w(_1, _2); } // CHECK-LABEL: @xvabsd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvabsd_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvabsd_d(_1, _2); } // CHECK-LABEL: @xvabsd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvabsd.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvabsd_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvabsd_bu(_1, _2); } // CHECK-LABEL: @xvabsd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvabsd.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvabsd_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvabsd_hu(_1, _2); } // CHECK-LABEL: @xvabsd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvabsd.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvabsd_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvabsd_wu(_1, _2); } // CHECK-LABEL: @xvabsd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvabsd.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvabsd_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvabsd_du(_1, _2); } // CHECK-LABEL: @xvmul_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmul.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmul.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmul_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmul_b(_1, _2); } // CHECK-LABEL: @xvmul_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmul.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmul.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmul_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmul_h(_1, _2); } // CHECK-LABEL: @xvmul_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmul.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmul.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmul_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmul_w(_1, _2); } // CHECK-LABEL: @xvmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmul.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmul.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmul_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmul_d(_1, _2); } // CHECK-LABEL: @xvmadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmadd.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmadd.b(<32 x i8> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmadd_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __builtin_lasx_xvmadd_b(_1, _2, _3); } // CHECK-LABEL: @xvmadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmadd.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmadd.h(<16 x i16> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmadd_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __builtin_lasx_xvmadd_h(_1, _2, _3); } // CHECK-LABEL: @xvmadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmadd.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmadd.w(<8 x i32> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmadd_w(v8i32 _1, v8i32 _2, v8i32 _3) { return __builtin_lasx_xvmadd_w(_1, _2, _3); } // CHECK-LABEL: @xvmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmadd.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmadd.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmadd_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __builtin_lasx_xvmadd_d(_1, _2, _3); } // CHECK-LABEL: @xvmsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsub.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsub.b(<32 x i8> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmsub_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __builtin_lasx_xvmsub_b(_1, _2, _3); } // CHECK-LABEL: @xvmsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmsub.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmsub.h(<16 x i16> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmsub_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __builtin_lasx_xvmsub_h(_1, _2, _3); } // CHECK-LABEL: @xvmsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmsub.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmsub.w(<8 x i32> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmsub_w(v8i32 _1, v8i32 _2, v8i32 _3) { return __builtin_lasx_xvmsub_w(_1, _2, _3); } // CHECK-LABEL: @xvmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmsub.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmsub.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmsub_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __builtin_lasx_xvmsub_d(_1, _2, _3); } // CHECK-LABEL: @xvdiv_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvdiv_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvdiv_b(_1, _2); } // CHECK-LABEL: @xvdiv_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvdiv_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvdiv_h(_1, _2); } // CHECK-LABEL: @xvdiv_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvdiv_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvdiv_w(_1, _2); } // CHECK-LABEL: @xvdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvdiv_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvdiv_d(_1, _2); } // CHECK-LABEL: @xvdiv_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvdiv.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvdiv_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvdiv_bu(_1, _2); } // CHECK-LABEL: @xvdiv_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvdiv.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvdiv_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvdiv_hu(_1, _2); } // CHECK-LABEL: @xvdiv_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvdiv.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvdiv_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvdiv_wu(_1, _2); } // CHECK-LABEL: @xvdiv_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvdiv.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvdiv_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvdiv_du(_1, _2); } // CHECK-LABEL: @xvhaddw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvhaddw_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvhaddw_h_b(_1, _2); } // CHECK-LABEL: @xvhaddw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvhaddw_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvhaddw_w_h(_1, _2); } // CHECK-LABEL: @xvhaddw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhaddw_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvhaddw_d_w(_1, _2); } // CHECK-LABEL: @xvhaddw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.hu.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhaddw.hu.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvhaddw_hu_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvhaddw_hu_bu(_1, _2); } // CHECK-LABEL: @xvhaddw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.wu.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhaddw.wu.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvhaddw_wu_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvhaddw_wu_hu(_1, _2); } // CHECK-LABEL: @xvhaddw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.du.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.du.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvhaddw_du_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvhaddw_du_wu(_1, _2); } // CHECK-LABEL: @xvhsubw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvhsubw_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvhsubw_h_b(_1, _2); } // CHECK-LABEL: @xvhsubw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvhsubw_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvhsubw_w_h(_1, _2); } // CHECK-LABEL: @xvhsubw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhsubw_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvhsubw_d_w(_1, _2); } // CHECK-LABEL: @xvhsubw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.hu.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvhsubw.hu.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvhsubw_hu_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvhsubw_hu_bu(_1, _2); } // CHECK-LABEL: @xvhsubw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.wu.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvhsubw.wu.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvhsubw_wu_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvhsubw_wu_hu(_1, _2); } // CHECK-LABEL: @xvhsubw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.du.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.du.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhsubw_du_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvhsubw_du_wu(_1, _2); } // CHECK-LABEL: @xvmod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmod_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmod_b(_1, _2); } // CHECK-LABEL: @xvmod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmod_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmod_h(_1, _2); } // CHECK-LABEL: @xvmod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmod_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmod_w(_1, _2); } // CHECK-LABEL: @xvmod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmod_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmod_d(_1, _2); } // CHECK-LABEL: @xvmod_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmod.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmod_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvmod_bu(_1, _2); } // CHECK-LABEL: @xvmod_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmod.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmod_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvmod_hu(_1, _2); } // CHECK-LABEL: @xvmod_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmod.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmod_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvmod_wu(_1, _2); } // CHECK-LABEL: @xvmod_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmod.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmod_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvmod_du(_1, _2); } // CHECK-LABEL: @xvrepl128vei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrepl128vei_b(v32i8 _1) { return __builtin_lasx_xvrepl128vei_b(_1, 1); } // CHECK-LABEL: @xvrepl128vei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrepl128vei_h(v16i16 _1) { return __builtin_lasx_xvrepl128vei_h(_1, 1); } // CHECK-LABEL: @xvrepl128vei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrepl128vei_w(v8i32 _1) { return __builtin_lasx_xvrepl128vei_w(_1, 1); } // CHECK-LABEL: @xvrepl128vei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrepl128vei_d(v4i64 _1) { return __builtin_lasx_xvrepl128vei_d(_1, 1); } // CHECK-LABEL: @xvpickev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickev.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickev.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpickev_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvpickev_b(_1, _2); } // CHECK-LABEL: @xvpickev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickev.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickev.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpickev_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvpickev_h(_1, _2); } // CHECK-LABEL: @xvpickev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickev.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickev.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpickev_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvpickev_w(_1, _2); } // CHECK-LABEL: @xvpickev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickev.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickev.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpickev_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvpickev_d(_1, _2); } // CHECK-LABEL: @xvpickod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickod.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpickod.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpickod_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvpickod_b(_1, _2); } // CHECK-LABEL: @xvpickod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickod.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpickod.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpickod_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvpickod_h(_1, _2); } // CHECK-LABEL: @xvpickod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickod.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickod.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpickod_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvpickod_w(_1, _2); } // CHECK-LABEL: @xvpickod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickod.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickod.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpickod_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvpickod_d(_1, _2); } // CHECK-LABEL: @xvilvh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvh.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvh.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvilvh_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvilvh_b(_1, _2); } // CHECK-LABEL: @xvilvh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvh.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvh.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvilvh_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvilvh_h(_1, _2); } // CHECK-LABEL: @xvilvh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvh.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvh.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvilvh_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvilvh_w(_1, _2); } // CHECK-LABEL: @xvilvh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvh.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvh.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvilvh_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvilvh_d(_1, _2); } // CHECK-LABEL: @xvilvl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvl.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvilvl.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvilvl_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvilvl_b(_1, _2); } // CHECK-LABEL: @xvilvl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvl.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvilvl.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvilvl_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvilvl_h(_1, _2); } // CHECK-LABEL: @xvilvl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvl.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvilvl.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvilvl_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvilvl_w(_1, _2); } // CHECK-LABEL: @xvilvl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvl.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvilvl.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvilvl_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvilvl_d(_1, _2); } // CHECK-LABEL: @xvpackev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackev.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackev.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpackev_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvpackev_b(_1, _2); } // CHECK-LABEL: @xvpackev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackev.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackev.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpackev_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvpackev_h(_1, _2); } // CHECK-LABEL: @xvpackev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackev.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackev.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpackev_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvpackev_w(_1, _2); } // CHECK-LABEL: @xvpackev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackev.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackev.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpackev_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvpackev_d(_1, _2); } // CHECK-LABEL: @xvpackod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackod.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpackod.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpackod_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvpackod_b(_1, _2); } // CHECK-LABEL: @xvpackod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackod.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpackod.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpackod_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvpackod_h(_1, _2); } // CHECK-LABEL: @xvpackod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackod.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpackod.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpackod_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvpackod_w(_1, _2); } // CHECK-LABEL: @xvpackod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackod.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpackod.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpackod_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvpackod_d(_1, _2); } // CHECK-LABEL: @xvshuf_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf.b(<32 x i8> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvshuf_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __builtin_lasx_xvshuf_b(_1, _2, _3); } // CHECK-LABEL: @xvshuf_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf.h(<16 x i16> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvshuf_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __builtin_lasx_xvshuf_h(_1, _2, _3); } // CHECK-LABEL: @xvshuf_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf.w(<8 x i32> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvshuf_w(v8i32 _1, v8i32 _2, v8i32 _3) { return __builtin_lasx_xvshuf_w(_1, _2, _3); } // CHECK-LABEL: @xvshuf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvshuf_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __builtin_lasx_xvshuf_d(_1, _2, _3); } // CHECK-LABEL: @xvand_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvand.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvand.v(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvand_v(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvand_v(_1, _2); } // CHECK-LABEL: @xvandi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvandi_b(v32u8 _1) { return __builtin_lasx_xvandi_b(_1, 1); } // CHECK-LABEL: @xvor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvor.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvor.v(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvor_v(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvor_v(_1, _2); } // CHECK-LABEL: @xvori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvori_b(v32u8 _1) { return __builtin_lasx_xvori_b(_1, 1); } // CHECK-LABEL: @xvnor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnor.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnor.v(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvnor_v(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvnor_v(_1, _2); } // CHECK-LABEL: @xvnori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvnori_b(v32u8 _1) { return __builtin_lasx_xvnori_b(_1, 1); } // CHECK-LABEL: @xvxor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxor.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxor.v(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvxor_v(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvxor_v(_1, _2); } // CHECK-LABEL: @xvxori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvxori_b(v32u8 _1) { return __builtin_lasx_xvxori_b(_1, 1); } // CHECK-LABEL: @xvbitsel_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitsel.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitsel.v(<32 x i8> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitsel_v(v32u8 _1, v32u8 _2, v32u8 _3) { return __builtin_lasx_xvbitsel_v(_1, _2, _3); } // CHECK-LABEL: @xvbitseli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvbitseli_b(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvbitseli_b(_1, _2, 1); } // CHECK-LABEL: @xvshuf4i_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvshuf4i_b(v32i8 _1) { return __builtin_lasx_xvshuf4i_b(_1, 1); } // CHECK-LABEL: @xvshuf4i_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvshuf4i_h(v16i16 _1) { return __builtin_lasx_xvshuf4i_h(_1, 1); } // CHECK-LABEL: @xvshuf4i_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvshuf4i_w(v8i32 _1) { return __builtin_lasx_xvshuf4i_w(_1, 1); } // CHECK-LABEL: @xvreplgr2vr_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplgr2vr.b(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplgr2vr_b(int _1) { return __builtin_lasx_xvreplgr2vr_b(_1); } // CHECK-LABEL: @xvreplgr2vr_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplgr2vr.h(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: store <16 x i16> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvreplgr2vr_h(int _1) { return __builtin_lasx_xvreplgr2vr_h(_1); } // CHECK-LABEL: @xvreplgr2vr_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplgr2vr.w(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: store <8 x i32> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvreplgr2vr_w(int _1) { return __builtin_lasx_xvreplgr2vr_w(_1); } // CHECK-LABEL: @xvreplgr2vr_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[CONV:%.*]] = sext i32 [[_1:%.*]] to i64 // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplgr2vr.d(i64 [[CONV]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvreplgr2vr_d(int _1) { return __builtin_lasx_xvreplgr2vr_d(_1); } // CHECK-LABEL: @xvpcnt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpcnt.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpcnt.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpcnt_b(v32i8 _1) { return __builtin_lasx_xvpcnt_b(_1); } // CHECK-LABEL: @xvpcnt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpcnt.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvpcnt.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvpcnt_h(v16i16 _1) { return __builtin_lasx_xvpcnt_h(_1); } // CHECK-LABEL: @xvpcnt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpcnt.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpcnt.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpcnt_w(v8i32 _1) { return __builtin_lasx_xvpcnt_w(_1); } // CHECK-LABEL: @xvpcnt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpcnt.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpcnt.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpcnt_d(v4i64 _1) { return __builtin_lasx_xvpcnt_d(_1); } // CHECK-LABEL: @xvclo_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclo.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclo.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvclo_b(v32i8 _1) { return __builtin_lasx_xvclo_b(_1); } // CHECK-LABEL: @xvclo_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclo.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclo.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvclo_h(v16i16 _1) { return __builtin_lasx_xvclo_h(_1); } // CHECK-LABEL: @xvclo_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclo.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclo.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvclo_w(v8i32 _1) { return __builtin_lasx_xvclo_w(_1); } // CHECK-LABEL: @xvclo_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclo.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclo.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvclo_d(v4i64 _1) { return __builtin_lasx_xvclo_d(_1); } // CHECK-LABEL: @xvclz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvclz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvclz_b(v32i8 _1) { return __builtin_lasx_xvclz_b(_1); } // CHECK-LABEL: @xvclz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvclz.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvclz_h(v16i16 _1) { return __builtin_lasx_xvclz_h(_1); } // CHECK-LABEL: @xvclz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvclz.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvclz_w(v8i32 _1) { return __builtin_lasx_xvclz_w(_1); } // CHECK-LABEL: @xvclz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvclz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvclz_d(v4i64 _1) { return __builtin_lasx_xvclz_d(_1); } // CHECK-LABEL: @xvfadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfadd.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfadd.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfadd_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfadd_s(_1, _2); } // CHECK-LABEL: @xvfadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfadd.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfadd.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfadd_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfadd_d(_1, _2); } // CHECK-LABEL: @xvfsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsub.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsub.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfsub_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfsub_s(_1, _2); } // CHECK-LABEL: @xvfsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsub.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsub.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfsub_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfsub_d(_1, _2); } // CHECK-LABEL: @xvfmul_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmul.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmul.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmul_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfmul_s(_1, _2); } // CHECK-LABEL: @xvfmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmul.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmul.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmul_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfmul_d(_1, _2); } // CHECK-LABEL: @xvfdiv_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfdiv.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfdiv.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfdiv_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfdiv_s(_1, _2); } // CHECK-LABEL: @xvfdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfdiv.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfdiv.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfdiv_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfdiv_d(_1, _2); } // CHECK-LABEL: @xvfcvt_h_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfcvt.h.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfcvt.h.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvfcvt_h_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcvt_h_s(_1, _2); } // CHECK-LABEL: @xvfcvt_s_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvt.s.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvt.s.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfcvt_s_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcvt_s_d(_1, _2); } // CHECK-LABEL: @xvfmin_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmin.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmin.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmin_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfmin_s(_1, _2); } // CHECK-LABEL: @xvfmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmin.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmin.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmin_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfmin_d(_1, _2); } // CHECK-LABEL: @xvfmina_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmina.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmina.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmina_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfmina_s(_1, _2); } // CHECK-LABEL: @xvfmina_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmina.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmina.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmina_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfmina_d(_1, _2); } // CHECK-LABEL: @xvfmax_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmax.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmax.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmax_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfmax_s(_1, _2); } // CHECK-LABEL: @xvfmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmax.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmax.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmax_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfmax_d(_1, _2); } // CHECK-LABEL: @xvfmaxa_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmaxa.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmaxa.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmaxa_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfmaxa_s(_1, _2); } // CHECK-LABEL: @xvfmaxa_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmaxa.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmaxa.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x double> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmaxa_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfmaxa_d(_1, _2); } // CHECK-LABEL: @xvfclass_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfclass.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfclass.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfclass_s(v8f32 _1) { return __builtin_lasx_xvfclass_s(_1); } // CHECK-LABEL: @xvfclass_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfclass.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfclass.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfclass_d(v4f64 _1) { return __builtin_lasx_xvfclass_d(_1); } // CHECK-LABEL: @xvfsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsqrt.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfsqrt.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfsqrt_s(v8f32 _1) { return __builtin_lasx_xvfsqrt_s(_1); } // CHECK-LABEL: @xvfsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsqrt.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfsqrt.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfsqrt_d(v4f64 _1) { return __builtin_lasx_xvfsqrt_d(_1); } // CHECK-LABEL: @xvfrecip_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrecip.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrecip.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfrecip_s(v8f32 _1) { return __builtin_lasx_xvfrecip_s(_1); } // CHECK-LABEL: @xvfrecip_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrecip.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrecip.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfrecip_d(v4f64 _1) { return __builtin_lasx_xvfrecip_d(_1); } // CHECK-LABEL: @xvfrint_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrint.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrint.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfrint_s(v8f32 _1) { return __builtin_lasx_xvfrint_s(_1); } // CHECK-LABEL: @xvfrint_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrint.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrint.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfrint_d(v4f64 _1) { return __builtin_lasx_xvfrint_d(_1); } // CHECK-LABEL: @xvfrsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrsqrt.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrsqrt.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfrsqrt_s(v8f32 _1) { return __builtin_lasx_xvfrsqrt_s(_1); } // CHECK-LABEL: @xvfrsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrsqrt.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrsqrt.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfrsqrt_d(v4f64 _1) { return __builtin_lasx_xvfrsqrt_d(_1); } // CHECK-LABEL: @xvflogb_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvflogb.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvflogb.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvflogb_s(v8f32 _1) { return __builtin_lasx_xvflogb_s(_1); } // CHECK-LABEL: @xvflogb_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvflogb.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvflogb.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvflogb_d(v4f64 _1) { return __builtin_lasx_xvflogb_d(_1); } // CHECK-LABEL: @xvfcvth_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvth.s.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvth.s.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfcvth_s_h(v16i16 _1) { return __builtin_lasx_xvfcvth_s_h(_1); } // CHECK-LABEL: @xvfcvth_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvth.d.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvth.d.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfcvth_d_s(v8f32 _1) { return __builtin_lasx_xvfcvth_d_s(_1); } // CHECK-LABEL: @xvfcvtl_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvtl.s.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfcvtl.s.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfcvtl_s_h(v16i16 _1) { return __builtin_lasx_xvfcvtl_s_h(_1); } // CHECK-LABEL: @xvfcvtl_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvtl.d.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfcvtl.d.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfcvtl_d_s(v8f32 _1) { return __builtin_lasx_xvfcvtl_d_s(_1); } // CHECK-LABEL: @xvftint_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftint_w_s(v8f32 _1) { return __builtin_lasx_xvftint_w_s(_1); } // CHECK-LABEL: @xvftint_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftint_l_d(v4f64 _1) { return __builtin_lasx_xvftint_l_d(_1); } // CHECK-LABEL: @xvftint_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.wu.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.wu.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvftint_wu_s(v8f32 _1) { return __builtin_lasx_xvftint_wu_s(_1); } // CHECK-LABEL: @xvftint_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.lu.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftint.lu.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvftint_lu_d(v4f64 _1) { return __builtin_lasx_xvftint_lu_d(_1); } // CHECK-LABEL: @xvftintrz_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrz_w_s(v8f32 _1) { return __builtin_lasx_xvftintrz_w_s(_1); } // CHECK-LABEL: @xvftintrz_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrz_l_d(v4f64 _1) { return __builtin_lasx_xvftintrz_l_d(_1); } // CHECK-LABEL: @xvftintrz_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.wu.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.wu.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvftintrz_wu_s(v8f32 _1) { return __builtin_lasx_xvftintrz_wu_s(_1); } // CHECK-LABEL: @xvftintrz_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.lu.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrz.lu.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvftintrz_lu_d(v4f64 _1) { return __builtin_lasx_xvftintrz_lu_d(_1); } // CHECK-LABEL: @xvffint_s_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvffint_s_w(v8i32 _1) { return __builtin_lasx_xvffint_s_w(_1); } // CHECK-LABEL: @xvffint_d_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.l(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.l(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffint_d_l(v4i64 _1) { return __builtin_lasx_xvffint_d_l(_1); } // CHECK-LABEL: @xvffint_s_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.wu(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.wu(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvffint_s_wu(v8u32 _1) { return __builtin_lasx_xvffint_s_wu(_1); } // CHECK-LABEL: @xvffint_d_lu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.lu(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffint.d.lu(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffint_d_lu(v4u64 _1) { return __builtin_lasx_xvffint_d_lu(_1); } // CHECK-LABEL: @xvreplve_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve.b(<32 x i8> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve.b(<32 x i8> [[_1]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplve_b(v32i8 _1, int _2) { return __builtin_lasx_xvreplve_b(_1, _2); } // CHECK-LABEL: @xvreplve_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve.h(<16 x i16> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve.h(<16 x i16> [[_1]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvreplve_h(v16i16 _1, int _2) { return __builtin_lasx_xvreplve_h(_1, _2); } // CHECK-LABEL: @xvreplve_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve.w(<8 x i32> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve.w(<8 x i32> [[_1]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvreplve_w(v8i32 _1, int _2) { return __builtin_lasx_xvreplve_w(_1, _2); } // CHECK-LABEL: @xvreplve_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve.d(<4 x i64> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve.d(<4 x i64> [[_1]], i32 [[_2:%.*]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvreplve_d(v4i64 _1, int _2) { return __builtin_lasx_xvreplve_d(_1, _2); } // CHECK-LABEL: @xvpermi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpermi_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvpermi_w(_1, _2, 1); } // CHECK-LABEL: @xvandn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandn.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvandn.v(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvandn_v(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvandn_v(_1, _2); } // CHECK-LABEL: @xvneg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvneg.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvneg.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvneg_b(v32i8 _1) { return __builtin_lasx_xvneg_b(_1); } // CHECK-LABEL: @xvneg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvneg.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvneg.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvneg_h(v16i16 _1) { return __builtin_lasx_xvneg_h(_1); } // CHECK-LABEL: @xvneg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvneg.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvneg.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvneg_w(v8i32 _1) { return __builtin_lasx_xvneg_w(_1); } // CHECK-LABEL: @xvneg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvneg.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvneg.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvneg_d(v4i64 _1) { return __builtin_lasx_xvneg_d(_1); } // CHECK-LABEL: @xvmuh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmuh_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmuh_b(_1, _2); } // CHECK-LABEL: @xvmuh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmuh_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmuh_h(_1, _2); } // CHECK-LABEL: @xvmuh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmuh_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmuh_w(_1, _2); } // CHECK-LABEL: @xvmuh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmuh_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmuh_d(_1, _2); } // CHECK-LABEL: @xvmuh_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmuh.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvmuh_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvmuh_bu(_1, _2); } // CHECK-LABEL: @xvmuh_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmuh.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmuh_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvmuh_hu(_1, _2); } // CHECK-LABEL: @xvmuh_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmuh.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmuh_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvmuh_wu(_1, _2); } // CHECK-LABEL: @xvmuh_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmuh.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmuh_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvmuh_du(_1, _2); } // CHECK-LABEL: @xvsllwil_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsllwil_h_b(v32i8 _1) { return __builtin_lasx_xvsllwil_h_b(_1, 1); } // CHECK-LABEL: @xvsllwil_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsllwil_w_h(v16i16 _1) { return __builtin_lasx_xvsllwil_w_h(_1, 1); } // CHECK-LABEL: @xvsllwil_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsllwil_d_w(v8i32 _1) { return __builtin_lasx_xvsllwil_d_w(_1, 1); } // CHECK-LABEL: @xvsllwil_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvsllwil_hu_bu(v32u8 _1) { return __builtin_lasx_xvsllwil_hu_bu(_1, 1); } // CHECK-LABEL: @xvsllwil_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvsllwil_wu_hu(v16u16 _1) { return __builtin_lasx_xvsllwil_wu_hu(_1, 1); } // CHECK-LABEL: @xvsllwil_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvsllwil_du_wu(v8u32 _1) { return __builtin_lasx_xvsllwil_du_wu(_1, 1); } // CHECK-LABEL: @xvsran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsran.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsran.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsran_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsran_b_h(_1, _2); } // CHECK-LABEL: @xvsran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsran.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsran.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsran_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsran_h_w(_1, _2); } // CHECK-LABEL: @xvsran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsran.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsran.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsran_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsran_w_d(_1, _2); } // CHECK-LABEL: @xvssran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssran_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssran_b_h(_1, _2); } // CHECK-LABEL: @xvssran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssran_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssran_h_w(_1, _2); } // CHECK-LABEL: @xvssran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssran_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssran_w_d(_1, _2); } // CHECK-LABEL: @xvssran_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssran.bu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssran_bu_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvssran_bu_h(_1, _2); } // CHECK-LABEL: @xvssran_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssran.hu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssran_hu_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvssran_hu_w(_1, _2); } // CHECK-LABEL: @xvssran_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssran.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssran_wu_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvssran_wu_d(_1, _2); } // CHECK-LABEL: @xvsrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarn.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrarn_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrarn_b_h(_1, _2); } // CHECK-LABEL: @xvsrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarn.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrarn_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrarn_h_w(_1, _2); } // CHECK-LABEL: @xvsrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrarn_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrarn_w_d(_1, _2); } // CHECK-LABEL: @xvssrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrarn_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrarn_b_h(_1, _2); } // CHECK-LABEL: @xvssrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrarn_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrarn_h_w(_1, _2); } // CHECK-LABEL: @xvssrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrarn_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrarn_w_d(_1, _2); } // CHECK-LABEL: @xvssrarn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarn.bu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrarn_bu_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvssrarn_bu_h(_1, _2); } // CHECK-LABEL: @xvssrarn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarn.hu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrarn_hu_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvssrarn_hu_w(_1, _2); } // CHECK-LABEL: @xvssrarn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarn.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrarn_wu_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvssrarn_wu_d(_1, _2); } // CHECK-LABEL: @xvsrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrln.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrln.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrln_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrln_b_h(_1, _2); } // CHECK-LABEL: @xvsrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrln.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrln.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrln_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrln_h_w(_1, _2); } // CHECK-LABEL: @xvsrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrln.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrln.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrln_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrln_w_d(_1, _2); } // CHECK-LABEL: @xvssrln_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.bu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrln_bu_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvssrln_bu_h(_1, _2); } // CHECK-LABEL: @xvssrln_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.hu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrln_hu_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvssrln_hu_w(_1, _2); } // CHECK-LABEL: @xvssrln_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrln_wu_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvssrln_wu_d(_1, _2); } // CHECK-LABEL: @xvsrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrn.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlrn_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrlrn_b_h(_1, _2); } // CHECK-LABEL: @xvsrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrn.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlrn_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrlrn_h_w(_1, _2); } // CHECK-LABEL: @xvsrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlrn_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrlrn_w_d(_1, _2); } // CHECK-LABEL: @xvssrlrn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.bu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.bu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrlrn_bu_h(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvssrlrn_bu_h(_1, _2); } // CHECK-LABEL: @xvssrlrn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.hu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.hu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrlrn_hu_w(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvssrlrn_hu_w(_1, _2); } // CHECK-LABEL: @xvssrlrn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.wu.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.wu.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrlrn_wu_d(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvssrlrn_wu_d(_1, _2); } // CHECK-LABEL: @xvfrstpi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvfrstpi_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvfrstpi_b(_1, _2, 1); } // CHECK-LABEL: @xvfrstpi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvfrstpi_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvfrstpi_h(_1, _2, 1); } // CHECK-LABEL: @xvfrstp_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstp.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvfrstp.b(<32 x i8> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <32 x i8> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvfrstp_b(v32i8 _1, v32i8 _2, v32i8 _3) { return __builtin_lasx_xvfrstp_b(_1, _2, _3); } // CHECK-LABEL: @xvfrstp_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstp.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvfrstp.h(<16 x i16> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvfrstp_h(v16i16 _1, v16i16 _2, v16i16 _3) { return __builtin_lasx_xvfrstp_h(_1, _2, _3); } // CHECK-LABEL: @xvshuf4i_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvshuf4i_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvshuf4i_d(_1, _2, 1); } // CHECK-LABEL: @xvbsrl_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvbsrl_v(v32i8 _1) { return __builtin_lasx_xvbsrl_v(_1, 1); } // CHECK-LABEL: @xvbsll_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvbsll_v(v32i8 _1) { return __builtin_lasx_xvbsll_v(_1, 1); } // CHECK-LABEL: @xvextrins_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvextrins_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvextrins_b(_1, _2, 1); } // CHECK-LABEL: @xvextrins_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvextrins_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvextrins_h(_1, _2, 1); } // CHECK-LABEL: @xvextrins_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvextrins_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvextrins_w(_1, _2, 1); } // CHECK-LABEL: @xvextrins_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvextrins_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvextrins_d(_1, _2, 1); } // CHECK-LABEL: @xvmskltz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskltz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskltz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmskltz_b(v32i8 _1) { return __builtin_lasx_xvmskltz_b(_1); } // CHECK-LABEL: @xvmskltz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmskltz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmskltz.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmskltz_h(v16i16 _1) { return __builtin_lasx_xvmskltz_h(_1); } // CHECK-LABEL: @xvmskltz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmskltz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmskltz.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmskltz_w(v8i32 _1) { return __builtin_lasx_xvmskltz_w(_1); } // CHECK-LABEL: @xvmskltz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmskltz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmskltz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmskltz_d(v4i64 _1) { return __builtin_lasx_xvmskltz_d(_1); } // CHECK-LABEL: @xvsigncov_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsigncov.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsigncov.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsigncov_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsigncov_b(_1, _2); } // CHECK-LABEL: @xvsigncov_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsigncov.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsigncov.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsigncov_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsigncov_h(_1, _2); } // CHECK-LABEL: @xvsigncov_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsigncov.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsigncov.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsigncov_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsigncov_w(_1, _2); } // CHECK-LABEL: @xvsigncov_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsigncov.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsigncov.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsigncov_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsigncov_d(_1, _2); } // CHECK-LABEL: @xvfmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmadd.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmadd.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmadd_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __builtin_lasx_xvfmadd_s(_1, _2, _3); } // CHECK-LABEL: @xvfmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmadd.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmadd.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmadd_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __builtin_lasx_xvfmadd_d(_1, _2, _3); } // CHECK-LABEL: @xvfmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmsub.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfmsub.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfmsub_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __builtin_lasx_xvfmsub_s(_1, _2, _3); } // CHECK-LABEL: @xvfmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmsub.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfmsub.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfmsub_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __builtin_lasx_xvfmsub_d(_1, _2, _3); } // CHECK-LABEL: @xvfnmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmadd.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmadd.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfnmadd_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __builtin_lasx_xvfnmadd_s(_1, _2, _3); } // CHECK-LABEL: @xvfnmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmadd.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmadd.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfnmadd_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __builtin_lasx_xvfnmadd_d(_1, _2, _3); } // CHECK-LABEL: @xvfnmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmsub.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]], <8 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x float>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfnmsub.s(<8 x float> [[_1]], <8 x float> [[_2]], <8 x float> [[_3]]) +// CHECK-NEXT: store <8 x float> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvfnmsub_s(v8f32 _1, v8f32 _2, v8f32 _3) { return __builtin_lasx_xvfnmsub_s(_1, _2, _3); } // CHECK-LABEL: @xvfnmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmsub.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]], <4 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x double>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfnmsub.d(<4 x double> [[_1]], <4 x double> [[_2]], <4 x double> [[_3]]) +// CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvfnmsub_d(v4f64 _1, v4f64 _2, v4f64 _3) { return __builtin_lasx_xvfnmsub_d(_1, _2, _3); } // CHECK-LABEL: @xvftintrne_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrne_w_s(v8f32 _1) { return __builtin_lasx_xvftintrne_w_s(_1); } // CHECK-LABEL: @xvftintrne_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrne.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrne.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrne_l_d(v4f64 _1) { return __builtin_lasx_xvftintrne_l_d(_1); } // CHECK-LABEL: @xvftintrp_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrp_w_s(v8f32 _1) { return __builtin_lasx_xvftintrp_w_s(_1); } // CHECK-LABEL: @xvftintrp_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrp.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrp.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrp_l_d(v4f64 _1) { return __builtin_lasx_xvftintrp_l_d(_1); } // CHECK-LABEL: @xvftintrm_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrm_w_s(v8f32 _1) { return __builtin_lasx_xvftintrm_w_s(_1); } // CHECK-LABEL: @xvftintrm_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrm.l.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrm.l.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrm_l_d(v4f64 _1) { return __builtin_lasx_xvftintrm_l_d(_1); } // CHECK-LABEL: @xvftint_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftint.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftint_w_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvftint_w_d(_1, _2); } // CHECK-LABEL: @xvffint_s_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.l(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvffint.s.l(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x float> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvffint_s_l(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvffint_s_l(_1, _2); } // CHECK-LABEL: @xvftintrz_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrz_w_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvftintrz_w_d(_1, _2); } // CHECK-LABEL: @xvftintrp_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrp_w_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvftintrp_w_d(_1, _2); } // CHECK-LABEL: @xvftintrm_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrm_w_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvftintrm_w_d(_1, _2); } // CHECK-LABEL: @xvftintrne_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvftintrne_w_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvftintrne_w_d(_1, _2); } // CHECK-LABEL: @xvftinth_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftinth.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftinth.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftinth_l_s(v8f32 _1) { return __builtin_lasx_xvftinth_l_s(_1); } // CHECK-LABEL: @xvftintl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintl.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintl.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintl_l_s(v8f32 _1) { return __builtin_lasx_xvftintl_l_s(_1); } // CHECK-LABEL: @xvffinth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffinth.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffinth.d.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffinth_d_w(v8i32 _1) { return __builtin_lasx_xvffinth_d_w(_1); } // CHECK-LABEL: @xvffintl_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffintl.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvffintl.d.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvffintl_d_w(v8i32 _1) { return __builtin_lasx_xvffintl_d_w(_1); } // CHECK-LABEL: @xvftintrzh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzh.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzh.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrzh_l_s(v8f32 _1) { return __builtin_lasx_xvftintrzh_l_s(_1); } // CHECK-LABEL: @xvftintrzl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzl.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrzl.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrzl_l_s(v8f32 _1) { return __builtin_lasx_xvftintrzl_l_s(_1); } // CHECK-LABEL: @xvftintrph_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrph.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrph.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrph_l_s(v8f32 _1) { return __builtin_lasx_xvftintrph_l_s(_1); } // CHECK-LABEL: @xvftintrpl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrpl.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrpl.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrpl_l_s(v8f32 _1) { return __builtin_lasx_xvftintrpl_l_s(_1); } // CHECK-LABEL: @xvftintrmh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrmh.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrmh.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrmh_l_s(v8f32 _1) { return __builtin_lasx_xvftintrmh_l_s(_1); } // CHECK-LABEL: @xvftintrml_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrml.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrml.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrml_l_s(v8f32 _1) { return __builtin_lasx_xvftintrml_l_s(_1); } // CHECK-LABEL: @xvftintrneh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrneh.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrneh.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrneh_l_s(v8f32 _1) { return __builtin_lasx_xvftintrneh_l_s(_1); } // CHECK-LABEL: @xvftintrnel_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrnel.l.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvftintrnel.l.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvftintrnel_l_s(v8f32 _1) { return __builtin_lasx_xvftintrnel_l_s(_1); } // CHECK-LABEL: @xvfrintrne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrne.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrne.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrne_s(v8f32 _1) { return __builtin_lasx_xvfrintrne_s(_1); } // CHECK-LABEL: @xvfrintrne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrne.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrne.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrne_d(v4f64 _1) { return __builtin_lasx_xvfrintrne_d(_1); } // CHECK-LABEL: @xvfrintrz_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrz.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrz.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrz_s(v8f32 _1) { return __builtin_lasx_xvfrintrz_s(_1); } // CHECK-LABEL: @xvfrintrz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrz.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrz.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrz_d(v4f64 _1) { return __builtin_lasx_xvfrintrz_d(_1); } // CHECK-LABEL: @xvfrintrp_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrp.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrp.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrp_s(v8f32 _1) { return __builtin_lasx_xvfrintrp_s(_1); } // CHECK-LABEL: @xvfrintrp_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrp.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrp.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrp_d(v4f64 _1) { return __builtin_lasx_xvfrintrp_d(_1); } // CHECK-LABEL: @xvfrintrm_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrm.s(<8 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[TMP0]] to <8 x i32> -// CHECK-NEXT: ret <8 x i32> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrintrm.s(<8 x float> [[_1]]) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfrintrm_s(v8f32 _1) { return __builtin_lasx_xvfrintrm_s(_1); } // CHECK-LABEL: @xvfrintrm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrm.d(<4 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[TMP0]] to <4 x i64> -// CHECK-NEXT: ret <4 x i64> [[TMP1]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrintrm.d(<4 x double> [[_1]]) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfrintrm_d(v4f64 _1) { return __builtin_lasx_xvfrintrm_d(_1); } // CHECK-LABEL: @xvld( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvld(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvld(void *_1) { return __builtin_lasx_xvld(_1, 1); } // CHECK-LABEL: @xvst( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvst(<32 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvst(<32 x i8> [[_1]], ptr [[_2:%.*]], i32 1) // CHECK-NEXT: ret void // void xvst(v32i8 _1, void *_2) { return __builtin_lasx_xvst(_1, _2, 1); } // CHECK-LABEL: @xvstelm_b( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> [[_1]], ptr [[_2:%.*]], i32 1, i32 1) // CHECK-NEXT: ret void // void xvstelm_b(v32i8 _1, void * _2) { return __builtin_lasx_xvstelm_b(_1, _2, 1, 1); } // CHECK-LABEL: @xvstelm_h( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> [[_1:%.*]], ptr [[_2:%.*]], i32 2, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> [[_1]], ptr [[_2:%.*]], i32 2, i32 1) // CHECK-NEXT: ret void // void xvstelm_h(v16i16 _1, void * _2) { return __builtin_lasx_xvstelm_h(_1, _2, 2, 1); } // CHECK-LABEL: @xvstelm_w( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> [[_1:%.*]], ptr [[_2:%.*]], i32 4, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> [[_1]], ptr [[_2:%.*]], i32 4, i32 1) // CHECK-NEXT: ret void // void xvstelm_w(v8i32 _1, void * _2) { return __builtin_lasx_xvstelm_w(_1, _2, 4, 1); } // CHECK-LABEL: @xvstelm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> [[_1:%.*]], ptr [[_2:%.*]], i32 8, i32 1) +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> [[_1]], ptr [[_2:%.*]], i32 8, i32 1) // CHECK-NEXT: ret void // void xvstelm_d(v4i64 _1, void * _2) { return __builtin_lasx_xvstelm_d(_1, _2, 8, 1); } // CHECK-LABEL: @xvinsve0_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvinsve0_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvinsve0_w(_1, _2, 1); } // CHECK-LABEL: @xvinsve0_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvinsve0_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvinsve0_d(_1, _2, 1); } // CHECK-LABEL: @xvpickve_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvpickve_w(v8i32 _1) { return __builtin_lasx_xvpickve_w(_1, 1); } // CHECK-LABEL: @xvpickve_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpickve_d(v4i64 _1) { return __builtin_lasx_xvpickve_d(_1, 1); } // CHECK-LABEL: @xvssrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrlrn_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrlrn_b_h(_1, _2); } // CHECK-LABEL: @xvssrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrlrn_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrlrn_h_w(_1, _2); } // CHECK-LABEL: @xvssrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrlrn_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrlrn_w_d(_1, _2); } // CHECK-LABEL: @xvssrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.b.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrln.b.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrln_b_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrln_b_h(_1, _2); } // CHECK-LABEL: @xvssrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.h.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrln.h.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrln_h_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrln_h_w(_1, _2); } // CHECK-LABEL: @xvssrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.w.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrln.w.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrln_w_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrln_w_d(_1, _2); } // CHECK-LABEL: @xvorn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvorn.v(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvorn.v(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvorn_v(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvorn_v(_1, _2); } // CHECK-LABEL: @xvldi( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvldi(i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvldi() { return __builtin_lasx_xvldi(1); } // CHECK-LABEL: @xvldx( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvldx(ptr [[_1:%.*]], i64 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvldx(void *_1) { return __builtin_lasx_xvldx(_1, 1); } // CHECK-LABEL: @xvstx( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstx(<32 x i8> [[_1:%.*]], ptr [[_2:%.*]], i64 1) +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @llvm.loongarch.lasx.xvstx(<32 x i8> [[_1]], ptr [[_2:%.*]], i64 1) // CHECK-NEXT: ret void // void xvstx(v32i8 _1, void *_2) { return __builtin_lasx_xvstx(_1, _2, 1); } // CHECK-LABEL: @xvextl_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.qu.du(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.qu.du(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvextl_qu_du(v4u64 _1) { return __builtin_lasx_xvextl_qu_du(_1); } // CHECK-LABEL: @xvinsgr2vr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> [[_1]], i32 1, i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvinsgr2vr_w(v8i32 _1) { return __builtin_lasx_xvinsgr2vr_w(_1, 1, 1); } // CHECK-LABEL: @xvinsgr2vr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> [[_1:%.*]], i64 1, i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> [[_1]], i64 1, i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvinsgr2vr_d(v4i64 _1) { return __builtin_lasx_xvinsgr2vr_d(_1, 1, 1); } // CHECK-LABEL: @xvreplve0_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplve0_b(v32i8 _1) { return __builtin_lasx_xvreplve0_b(_1); } // CHECK-LABEL: @xvreplve0_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve0.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvreplve0.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvreplve0_h(v16i16 _1) { return __builtin_lasx_xvreplve0_h(_1); } // CHECK-LABEL: @xvreplve0_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve0.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvreplve0.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvreplve0_w(v8i32 _1) { return __builtin_lasx_xvreplve0_w(_1); } // CHECK-LABEL: @xvreplve0_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve0.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvreplve0.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvreplve0_d(v4i64 _1) { return __builtin_lasx_xvreplve0_d(_1); } // CHECK-LABEL: @xvreplve0_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.q(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvreplve0.q(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvreplve0_q(v32i8 _1) { return __builtin_lasx_xvreplve0_q(_1); } // CHECK-LABEL: @vext2xv_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.h.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.h.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 vext2xv_h_b(v32i8 _1) { return __builtin_lasx_vext2xv_h_b(_1); } // CHECK-LABEL: @vext2xv_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_w_h(v16i16 _1) { return __builtin_lasx_vext2xv_w_h(_1); } // CHECK-LABEL: @vext2xv_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_d_w(v8i32 _1) { return __builtin_lasx_vext2xv_d_w(_1); } // CHECK-LABEL: @vext2xv_w_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_w_b(v32i8 _1) { return __builtin_lasx_vext2xv_w_b(_1); } // CHECK-LABEL: @vext2xv_d_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_d_h(v16i16 _1) { return __builtin_lasx_vext2xv_d_h(_1); } // CHECK-LABEL: @vext2xv_d_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_d_b(v32i8 _1) { return __builtin_lasx_vext2xv_d_b(_1); } // CHECK-LABEL: @vext2xv_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.hu.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.vext2xv.hu.bu(<32 x i8> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 vext2xv_hu_bu(v32i8 _1) { return __builtin_lasx_vext2xv_hu_bu(_1); } // CHECK-LABEL: @vext2xv_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.hu(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.hu(<16 x i16> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_wu_hu(v16i16 _1) { return __builtin_lasx_vext2xv_wu_hu(_1); } // CHECK-LABEL: @vext2xv_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.wu(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.wu(<8 x i32> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_du_wu(v8i32 _1) { return __builtin_lasx_vext2xv_du_wu(_1); } // CHECK-LABEL: @vext2xv_wu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.bu(<32 x i8> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 vext2xv_wu_bu(v32i8 _1) { return __builtin_lasx_vext2xv_wu_bu(_1); } // CHECK-LABEL: @vext2xv_du_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.hu(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.hu(<16 x i16> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_du_hu(v16i16 _1) { return __builtin_lasx_vext2xv_du_hu(_1); } // CHECK-LABEL: @vext2xv_du_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.bu(<32 x i8> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 vext2xv_du_bu(v32i8 _1) { return __builtin_lasx_vext2xv_du_bu(_1); } // CHECK-LABEL: @xvpermi_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvpermi_q(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvpermi_q(_1, _2, 1); } // CHECK-LABEL: @xvpermi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvpermi_d(v4i64 _1) { return __builtin_lasx_xvpermi_d(_1, 1); } // CHECK-LABEL: @xvperm_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvperm.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvperm.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvperm_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvperm_w(_1, _2); } // CHECK-LABEL: @xvldrepl_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvldrepl_b(void *_1) { return __builtin_lasx_xvldrepl_b(_1, 1); } // CHECK-LABEL: @xvldrepl_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(ptr [[_1:%.*]], i32 2) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: store <16 x i16> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvldrepl_h(void *_1) { return __builtin_lasx_xvldrepl_h(_1, 2); } // CHECK-LABEL: @xvldrepl_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(ptr [[_1:%.*]], i32 4) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: store <8 x i32> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvldrepl_w(void *_1) { return __builtin_lasx_xvldrepl_w(_1, 4); } // CHECK-LABEL: @xvldrepl_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(ptr [[_1:%.*]], i32 8) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvldrepl_d(void *_1) { return __builtin_lasx_xvldrepl_d(_1, 8); } // CHECK-LABEL: @xvpickve2gr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int xvpickve2gr_w(v8i32 _1) { return __builtin_lasx_xvpickve2gr_w(_1, 1); } // CHECK-LABEL: @xvpickve2gr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int xvpickve2gr_wu(v8i32 _1) { return __builtin_lasx_xvpickve2gr_wu(_1, 1); } // CHECK-LABEL: @xvpickve2gr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // long xvpickve2gr_d(v4i64 _1) { return __builtin_lasx_xvpickve2gr_d(_1, 1); } // CHECK-LABEL: @xvpickve2gr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // unsigned long int xvpickve2gr_du(v4i64 _1) { return __builtin_lasx_xvpickve2gr_du(_1, 1); } // CHECK-LABEL: @xvaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvaddwev_q_d(_1, _2); } // CHECK-LABEL: @xvaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvaddwev_d_w(_1, _2); } // CHECK-LABEL: @xvaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwev_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvaddwev_w_h(_1, _2); } // CHECK-LABEL: @xvaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwev_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvaddwev_h_b(_1, _2); } // CHECK-LABEL: @xvaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_q_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvaddwev_q_du(_1, _2); } // CHECK-LABEL: @xvaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_d_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvaddwev_d_wu(_1, _2); } // CHECK-LABEL: @xvaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwev_w_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvaddwev_w_hu(_1, _2); } // CHECK-LABEL: @xvaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwev_h_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvaddwev_h_bu(_1, _2); } // CHECK-LABEL: @xvsubwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsubwev_q_d(_1, _2); } // CHECK-LABEL: @xvsubwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsubwev_d_w(_1, _2); } // CHECK-LABEL: @xvsubwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwev_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsubwev_w_h(_1, _2); } // CHECK-LABEL: @xvsubwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwev_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsubwev_h_b(_1, _2); } // CHECK-LABEL: @xvsubwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_q_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvsubwev_q_du(_1, _2); } // CHECK-LABEL: @xvsubwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwev_d_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvsubwev_d_wu(_1, _2); } // CHECK-LABEL: @xvsubwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwev_w_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvsubwev_w_hu(_1, _2); } // CHECK-LABEL: @xvsubwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwev_h_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvsubwev_h_bu(_1, _2); } // CHECK-LABEL: @xvmulwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmulwev_q_d(_1, _2); } // CHECK-LABEL: @xvmulwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmulwev_d_w(_1, _2); } // CHECK-LABEL: @xvmulwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwev_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmulwev_w_h(_1, _2); } // CHECK-LABEL: @xvmulwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwev_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmulwev_h_b(_1, _2); } // CHECK-LABEL: @xvmulwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_q_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvmulwev_q_du(_1, _2); } // CHECK-LABEL: @xvmulwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_d_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvmulwev_d_wu(_1, _2); } // CHECK-LABEL: @xvmulwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwev_w_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvmulwev_w_hu(_1, _2); } // CHECK-LABEL: @xvmulwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwev_h_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvmulwev_h_bu(_1, _2); } // CHECK-LABEL: @xvaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvaddwod_q_d(_1, _2); } // CHECK-LABEL: @xvaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvaddwod_d_w(_1, _2); } // CHECK-LABEL: @xvaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwod_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvaddwod_w_h(_1, _2); } // CHECK-LABEL: @xvaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwod_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvaddwod_h_b(_1, _2); } // CHECK-LABEL: @xvaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_q_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvaddwod_q_du(_1, _2); } // CHECK-LABEL: @xvaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_d_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvaddwod_d_wu(_1, _2); } // CHECK-LABEL: @xvaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwod_w_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvaddwod_w_hu(_1, _2); } // CHECK-LABEL: @xvaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwod_h_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvaddwod_h_bu(_1, _2); } // CHECK-LABEL: @xvsubwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsubwod_q_d(_1, _2); } // CHECK-LABEL: @xvsubwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsubwod_d_w(_1, _2); } // CHECK-LABEL: @xvsubwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwod_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsubwod_w_h(_1, _2); } // CHECK-LABEL: @xvsubwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwod_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsubwod_h_b(_1, _2); } // CHECK-LABEL: @xvsubwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_q_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvsubwod_q_du(_1, _2); } // CHECK-LABEL: @xvsubwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsubwod_d_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvsubwod_d_wu(_1, _2); } // CHECK-LABEL: @xvsubwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsubwod_w_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvsubwod_w_hu(_1, _2); } // CHECK-LABEL: @xvsubwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsubwod_h_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvsubwod_h_bu(_1, _2); } // CHECK-LABEL: @xvmulwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvmulwod_q_d(_1, _2); } // CHECK-LABEL: @xvmulwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_d_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvmulwod_d_w(_1, _2); } // CHECK-LABEL: @xvmulwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwod_w_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvmulwod_w_h(_1, _2); } // CHECK-LABEL: @xvmulwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwod_h_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvmulwod_h_b(_1, _2); } // CHECK-LABEL: @xvmulwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_q_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvmulwod_q_du(_1, _2); } // CHECK-LABEL: @xvmulwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_d_wu(v8u32 _1, v8u32 _2) { return __builtin_lasx_xvmulwod_d_wu(_1, _2); } // CHECK-LABEL: @xvmulwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwod_w_hu(v16u16 _1, v16u16 _2) { return __builtin_lasx_xvmulwod_w_hu(_1, _2); } // CHECK-LABEL: @xvmulwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwod_h_bu(v32u8 _1, v32u8 _2) { return __builtin_lasx_xvmulwod_h_bu(_1, _2); } // CHECK-LABEL: @xvaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_d_wu_w(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvaddwev_d_wu_w(_1, _2); } // CHECK-LABEL: @xvaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwev_w_hu_h(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvaddwev_w_hu_h(_1, _2); } // CHECK-LABEL: @xvaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwev_h_bu_b(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvaddwev_h_bu_b(_1, _2); } // CHECK-LABEL: @xvmulwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_d_wu_w(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvmulwev_d_wu_w(_1, _2); } // CHECK-LABEL: @xvmulwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwev_w_hu_h(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvmulwev_w_hu_h(_1, _2); } // CHECK-LABEL: @xvmulwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwev_h_bu_b(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvmulwev_h_bu_b(_1, _2); } // CHECK-LABEL: @xvaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_d_wu_w(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvaddwod_d_wu_w(_1, _2); } // CHECK-LABEL: @xvaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvaddwod_w_hu_h(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvaddwod_w_hu_h(_1, _2); } // CHECK-LABEL: @xvaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvaddwod_h_bu_b(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvaddwod_h_bu_b(_1, _2); } // CHECK-LABEL: @xvmulwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_d_wu_w(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvmulwod_d_wu_w(_1, _2); } // CHECK-LABEL: @xvmulwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmulwod_w_hu_h(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvmulwod_w_hu_h(_1, _2); } // CHECK-LABEL: @xvmulwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmulwod_h_bu_b(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvmulwod_h_bu_b(_1, _2); } // CHECK-LABEL: @xvhaddw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhaddw_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvhaddw_q_d(_1, _2); } // CHECK-LABEL: @xvhaddw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.qu.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhaddw.qu.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvhaddw_qu_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvhaddw_qu_du(_1, _2); } // CHECK-LABEL: @xvhsubw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvhsubw_q_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvhsubw_q_d(_1, _2); } // CHECK-LABEL: @xvhsubw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.qu.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvhsubw.qu.du(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvhsubw_qu_du(v4u64 _1, v4u64 _2) { return __builtin_lasx_xvhsubw_qu_du(_1, _2); } // CHECK-LABEL: @xvmaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_q_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __builtin_lasx_xvmaddwev_q_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.w(<4 x i64> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_d_w(v4i64 _1, v8i32 _2, v8i32 _3) { return __builtin_lasx_xvmaddwev_d_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.h(<8 x i32> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwev_w_h(v8i32 _1, v16i16 _2, v16i16 _3) { return __builtin_lasx_xvmaddwev_w_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.b(<16 x i16> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwev_h_b(v16i16 _1, v32i8 _2, v32i8 _3) { return __builtin_lasx_xvmaddwev_h_b(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwev_q_du(v4u64 _1, v4u64 _2, v4u64 _3) { return __builtin_lasx_xvmaddwev_q_du(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu(<4 x i64> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwev_d_wu(v4u64 _1, v8u32 _2, v8u32 _3) { return __builtin_lasx_xvmaddwev_d_wu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu(<8 x i32> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmaddwev_w_hu(v8u32 _1, v16u16 _2, v16u16 _3) { return __builtin_lasx_xvmaddwev_w_hu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu(<16 x i16> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmaddwev_h_bu(v16u16 _1, v32u8 _2, v32u8 _3) { return __builtin_lasx_xvmaddwev_h_bu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_q_d(v4i64 _1, v4i64 _2, v4i64 _3) { return __builtin_lasx_xvmaddwod_q_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.w(<4 x i64> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_d_w(v4i64 _1, v8i32 _2, v8i32 _3) { return __builtin_lasx_xvmaddwod_d_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.h(<8 x i32> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwod_w_h(v8i32 _1, v16i16 _2, v16i16 _3) { return __builtin_lasx_xvmaddwod_w_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.b(<16 x i16> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwod_h_b(v16i16 _1, v32i8 _2, v32i8 _3) { return __builtin_lasx_xvmaddwod_h_b(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwod_q_du(v4u64 _1, v4u64 _2, v4u64 _3) { return __builtin_lasx_xvmaddwod_q_du(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu(<4 x i64> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvmaddwod_d_wu(v4u64 _1, v8u32 _2, v8u32 _3) { return __builtin_lasx_xvmaddwod_d_wu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu(<8 x i32> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvmaddwod_w_hu(v8u32 _1, v16u16 _2, v16u16 _3) { return __builtin_lasx_xvmaddwod_w_hu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu(<16 x i16> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvmaddwod_h_bu(v16u16 _1, v32u8 _2, v32u8 _3) { return __builtin_lasx_xvmaddwod_h_bu(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_q_du_d(v4i64 _1, v4u64 _2, v4i64 _3) { return __builtin_lasx_xvmaddwev_q_du_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu.w(<4 x i64> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwev_d_wu_w(v4i64 _1, v8u32 _2, v8i32 _3) { return __builtin_lasx_xvmaddwev_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu.h(<8 x i32> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwev_w_hu_h(v8i32 _1, v16u16 _2, v16i16 _3) { return __builtin_lasx_xvmaddwev_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu.b(<16 x i16> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwev_h_bu_b(v16i16 _1, v32u8 _2, v32i8 _3) { return __builtin_lasx_xvmaddwev_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], <4 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <4 x i64>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]], <4 x i64> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_q_du_d(v4i64 _1, v4u64 _2, v4i64 _3) { return __builtin_lasx_xvmaddwod_q_du_d(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu.w(<4 x i64> [[_1:%.*]], <8 x i32> [[_2:%.*]], <8 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <8 x i32>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu.w(<4 x i64> [[_1]], <8 x i32> [[_2]], <8 x i32> [[_3]]) +// CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmaddwod_d_wu_w(v4i64 _1, v8u32 _2, v8i32 _3) { return __builtin_lasx_xvmaddwod_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu.h(<8 x i32> [[_1:%.*]], <16 x i16> [[_2:%.*]], <16 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <16 x i16>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu.h(<8 x i32> [[_1]], <16 x i16> [[_2]], <16 x i16> [[_3]]) +// CHECK-NEXT: store <8 x i32> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvmaddwod_w_hu_h(v8i32 _1, v16u16 _2, v16i16 _3) { return __builtin_lasx_xvmaddwod_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @xvmaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu.b(<16 x i16> [[_1:%.*]], <32 x i8> [[_2:%.*]], <32 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_3:%.*]] = load <32 x i8>, ptr [[TMP2:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu.b(<16 x i16> [[_1]], <32 x i8> [[_2]], <32 x i8> [[_3]]) +// CHECK-NEXT: store <16 x i16> [[TMP3]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvmaddwod_h_bu_b(v16i16 _1, v32u8 _2, v32i8 _3) { return __builtin_lasx_xvmaddwod_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @xvrotr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotr.b(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotr.b(<32 x i8> [[_1]], <32 x i8> [[_2]]) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrotr_b(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvrotr_b(_1, _2); } // CHECK-LABEL: @xvrotr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotr.h(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotr.h(<16 x i16> [[_1]], <16 x i16> [[_2]]) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrotr_h(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvrotr_h(_1, _2); } // CHECK-LABEL: @xvrotr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotr.w(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotr.w(<8 x i32> [[_1]], <8 x i32> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrotr_w(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvrotr_w(_1, _2); } // CHECK-LABEL: @xvrotr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotr.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotr.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrotr_d(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvrotr_d(_1, _2); } // CHECK-LABEL: @xvadd_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvadd.q(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvadd_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvadd_q(_1, _2); } // CHECK-LABEL: @xvsub_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsub.q(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsub_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsub_q(_1, _2); } // CHECK-LABEL: @xvaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwev_q_du_d(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvaddwev_q_du_d(_1, _2); } // CHECK-LABEL: @xvaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvaddwod_q_du_d(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvaddwod_q_du_d(_1, _2); } // CHECK-LABEL: @xvmulwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwev_q_du_d(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvmulwev_q_du_d(_1, _2); } // CHECK-LABEL: @xvmulwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du.d(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du.d(<4 x i64> [[_1]], <4 x i64> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvmulwod_q_du_d(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvmulwod_q_du_d(_1, _2); } // CHECK-LABEL: @xvmskgez_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskgez.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmskgez.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmskgez_b(v32i8 _1) { return __builtin_lasx_xvmskgez_b(_1); } // CHECK-LABEL: @xvmsknz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsknz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvmsknz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvmsknz_b(v32i8 _1) { return __builtin_lasx_xvmsknz_b(_1); } // CHECK-LABEL: @xvexth_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.h.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.h.b(<32 x i8> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvexth_h_b(v32i8 _1) { return __builtin_lasx_xvexth_h_b(_1); } // CHECK-LABEL: @xvexth_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.w.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.w.h(<16 x i16> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvexth_w_h(v16i16 _1) { return __builtin_lasx_xvexth_w_h(_1); } // CHECK-LABEL: @xvexth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.d.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.d.w(<8 x i32> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvexth_d_w(v8i32 _1) { return __builtin_lasx_xvexth_d_w(_1); } // CHECK-LABEL: @xvexth_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.q.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.q.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvexth_q_d(v4i64 _1) { return __builtin_lasx_xvexth_q_d(_1); } // CHECK-LABEL: @xvexth_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.hu.bu(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvexth.hu.bu(<32 x i8> [[_1]]) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvexth_hu_bu(v32u8 _1) { return __builtin_lasx_xvexth_hu_bu(_1); } // CHECK-LABEL: @xvexth_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.wu.hu(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvexth.wu.hu(<16 x i16> [[_1]]) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvexth_wu_hu(v16u16 _1) { return __builtin_lasx_xvexth_wu_hu(_1); } // CHECK-LABEL: @xvexth_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.du.wu(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.du.wu(<8 x i32> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvexth_du_wu(v8u32 _1) { return __builtin_lasx_xvexth_du_wu(_1); } // CHECK-LABEL: @xvexth_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.qu.du(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvexth.qu.du(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvexth_qu_du(v4u64 _1) { return __builtin_lasx_xvexth_qu_du(_1); } // CHECK-LABEL: @xvrotri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> [[_1]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrotri_b(v32i8 _1) { return __builtin_lasx_xvrotri_b(_1, 1); } // CHECK-LABEL: @xvrotri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> [[_1]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrotri_h(v16i16 _1) { return __builtin_lasx_xvrotri_h(_1, 1); } // CHECK-LABEL: @xvrotri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> [[_1]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrotri_w(v8i32 _1) { return __builtin_lasx_xvrotri_w(_1, 1); } // CHECK-LABEL: @xvrotri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> [[_1]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrotri_d(v4i64 _1) { return __builtin_lasx_xvrotri_d(_1, 1); } // CHECK-LABEL: @xvextl_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.q.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvextl.q.d(<4 x i64> [[_1]]) +// CHECK-NEXT: store <4 x i64> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvextl_q_d(v4i64 _1) { return __builtin_lasx_xvextl_q_d(_1); } // CHECK-LABEL: @xvsrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlni_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlni_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlni_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlni_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrlrni_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrlrni_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrlrni_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrlrni_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrlni_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvssrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrlni_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrlni_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrlni_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrlni_bu_h(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvssrlni_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrlni_hu_w(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvssrlni_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrlni_wu_d(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvssrlni_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrlni_du_q(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvssrlni_du_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrlrni_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvssrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrlrni_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrlrni_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrlrni_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrlrni_bu_h(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvssrlrni_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrlrni_hu_w(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvssrlrni_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrlrni_wu_d(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvssrlrni_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrlrni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrlrni_du_q(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvssrlrni_du_q(_1, _2, 1); } // CHECK-LABEL: @xvsrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrani_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrani_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrani_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrani_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrani_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrani_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrani_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrani_d_q(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvsrarni_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvsrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvsrarni_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvsrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvsrarni_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvsrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvsrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvsrarni_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvsrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrani_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvssrani_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrani_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrani_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrani_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrani_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrani_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrani_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrani_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrani_bu_h(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvssrani_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrani_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrani_hu_w(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvssrani_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrani_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrani_wu_d(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvssrani_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrani_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrani_du_q(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvssrani_du_q(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvssrarni_b_h(v32i8 _1, v32i8 _2) { return __builtin_lasx_xvssrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvssrarni_h_w(v16i16 _1, v16i16 _2) { return __builtin_lasx_xvssrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvssrarni_w_d(v8i32 _1, v8i32 _2) { return __builtin_lasx_xvssrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvssrarni_d_q(v4i64 _1, v4i64 _2) { return __builtin_lasx_xvssrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> [[_1:%.*]], <32 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <32 x i8>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> [[_1]], <32 x i8> [[_2]], i32 1) +// CHECK-NEXT: store <32 x i8> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32u8 xvssrarni_bu_h(v32u8 _1, v32i8 _2) { return __builtin_lasx_xvssrarni_bu_h(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> [[_1:%.*]], <16 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <16 x i16>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> [[_1]], <16 x i16> [[_2]], i32 1) +// CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16u16 xvssrarni_hu_w(v16u16 _1, v16i16 _2) { return __builtin_lasx_xvssrarni_hu_w(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> [[_1:%.*]], <8 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x i32>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> [[_1]], <8 x i32> [[_2]], i32 1) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8u32 xvssrarni_wu_d(v8u32 _1, v8i32 _2) { return __builtin_lasx_xvssrarni_wu_d(_1, _2, 1); } // CHECK-LABEL: @xvssrarni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> [[_1:%.*]], <4 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x i64>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> [[_1]], <4 x i64> [[_2]], i32 1) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4u64 xvssrarni_du_q(v4u64 _1, v4i64 _2) { return __builtin_lasx_xvssrarni_du_q(_1, _2, 1); } // CHECK-LABEL: @xbnz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_b(v32u8 _1) { return __builtin_lasx_xbnz_b(_1); } // CHECK-LABEL: @xbnz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_d(v4u64 _1) { return __builtin_lasx_xbnz_d(_1); } // CHECK-LABEL: @xbnz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.h(<16 x i16> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_h(v16u16 _1) { return __builtin_lasx_xbnz_h(_1); } // CHECK-LABEL: @xbnz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.v(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.v(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_v(v32u8 _1) { return __builtin_lasx_xbnz_v(_1); } // CHECK-LABEL: @xbnz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbnz.w(<8 x i32> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbnz_w(v8u32 _1) { return __builtin_lasx_xbnz_w(_1); } // CHECK-LABEL: @xbz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.b(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.b(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_b(v32u8 _1) { return __builtin_lasx_xbz_b(_1); } // CHECK-LABEL: @xbz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.d(<4 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x i64>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.d(<4 x i64> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_d(v4u64 _1) { return __builtin_lasx_xbz_d(_1); } // CHECK-LABEL: @xbz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.h(<16 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <16 x i16>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.h(<16 x i16> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_h(v16u16 _1) { return __builtin_lasx_xbz_h(_1); } // CHECK-LABEL: @xbz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.v(<32 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <32 x i8>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.v(<32 x i8> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_v(v32u8 _1) { return __builtin_lasx_xbz_v(_1); } // CHECK-LABEL: @xbz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.w(<8 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lasx.xbz.w(<8 x i32> [[_1]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int xbz_w(v8u32 _1) { return __builtin_lasx_xbz_w(_1); } // CHECK-LABEL: @xvfcmp_caf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.caf.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.caf.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_caf_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_caf_d(_1, _2); } // CHECK-LABEL: @xvfcmp_caf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.caf.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.caf.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_caf_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_caf_s(_1, _2); } // CHECK-LABEL: @xvfcmp_ceq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.ceq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.ceq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_ceq_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_ceq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_ceq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.ceq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.ceq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_ceq_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_ceq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cle.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cle.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cle_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cle_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cle.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cle.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cle_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cle_s(_1, _2); } // CHECK-LABEL: @xvfcmp_clt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.clt.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.clt.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_clt_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_clt_d(_1, _2); } // CHECK-LABEL: @xvfcmp_clt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.clt.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.clt.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_clt_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_clt_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cne.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cne.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cne_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cne_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cne.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cne.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cne_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cne_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cor.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cor.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cor_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cor_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cor.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cor.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cor_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cor_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cueq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cueq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cueq_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cueq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cueq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cueq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cueq_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cueq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cule.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cule.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cule_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cule_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cule.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cule.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cule_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cule_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cult.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cult.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cult_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cult_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cult.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cult.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cult_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cult_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cun.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cun.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cun_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cun_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cune.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cune.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_cune_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_cune_d(_1, _2); } // CHECK-LABEL: @xvfcmp_cune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cune.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cune.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cune_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cune_s(_1, _2); } // CHECK-LABEL: @xvfcmp_cun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cun.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cun.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_cun_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_cun_s(_1, _2); } // CHECK-LABEL: @xvfcmp_saf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.saf.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.saf.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_saf_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_saf_d(_1, _2); } // CHECK-LABEL: @xvfcmp_saf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.saf.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.saf.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_saf_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_saf_s(_1, _2); } // CHECK-LABEL: @xvfcmp_seq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.seq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.seq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_seq_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_seq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_seq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.seq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.seq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_seq_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_seq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sle.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sle.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sle_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sle_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sle.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sle.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sle_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sle_s(_1, _2); } // CHECK-LABEL: @xvfcmp_slt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.slt.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.slt.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_slt_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_slt_d(_1, _2); } // CHECK-LABEL: @xvfcmp_slt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.slt.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.slt.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_slt_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_slt_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sne.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sne.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sne_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sne_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sne.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sne.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sne_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sne_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sor.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sor.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sor_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sor_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sor.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sor.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sor_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sor_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sueq.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sueq.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sueq_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sueq_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sueq.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sueq.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sueq_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sueq_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sule.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sule.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sule_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sule_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sule.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sule.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sule_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sule_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sult.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sult.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sult_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sult_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sult.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sult.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sult_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sult_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sun.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sun.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sun_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sun_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sune.d(<4 x double> [[_1:%.*]], <4 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <4 x double>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sune.d(<4 x double> [[_1]], <4 x double> [[_2]]) +// CHECK-NEXT: store <4 x i64> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvfcmp_sune_d(v4f64 _1, v4f64 _2) { return __builtin_lasx_xvfcmp_sune_d(_1, _2); } // CHECK-LABEL: @xvfcmp_sune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sune.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sune.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sune_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sune_s(_1, _2); } // CHECK-LABEL: @xvfcmp_sun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sun.s(<8 x float> [[_1:%.*]], <8 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[_2:%.*]] = load <8 x float>, ptr [[TMP1:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sun.s(<8 x float> [[_1]], <8 x float> [[_2]]) +// CHECK-NEXT: store <8 x i32> [[TMP2]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvfcmp_sun_s(v8f32 _1, v8f32 _2) { return __builtin_lasx_xvfcmp_sun_s(_1, _2); } // CHECK-LABEL: @xvpickve_d_f( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x double> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> [[_1]], i32 1) +// CHECK-NEXT: store <4 x double> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4f64 xvpickve_d_f(v4f64 _1) { return __builtin_lasx_xvpickve_d_f(_1, 1); } // CHECK-LABEL: @xvpickve_w_f( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x float> [[TMP0]] +// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> [[_1]], i32 1) +// CHECK-NEXT: store <8 x float> [[TMP1]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8f32 xvpickve_w_f(v8f32 _1) { return __builtin_lasx_xvpickve_w_f(_1, 1); } // CHECK-LABEL: @xvrepli_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 1) -// CHECK-NEXT: ret <32 x i8> [[TMP0]] +// CHECK-NEXT: store <32 x i8> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v32i8 xvrepli_b() { return __builtin_lasx_xvrepli_b(1); } // CHECK-LABEL: @xvrepli_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 1) -// CHECK-NEXT: ret <4 x i64> [[TMP0]] +// CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v4i64 xvrepli_d() { return __builtin_lasx_xvrepli_d(1); } // CHECK-LABEL: @xvrepli_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 1) -// CHECK-NEXT: ret <16 x i16> [[TMP0]] +// CHECK-NEXT: store <16 x i16> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v16i16 xvrepli_h() { return __builtin_lasx_xvrepli_h(1); } // CHECK-LABEL: @xvrepli_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 1) -// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// CHECK-NEXT: store <8 x i32> [[TMP0]], ptr [[AGG_RESULT:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void // v8i32 xvrepli_w() { return __builtin_lasx_xvrepli_w(1); } diff --git a/clang/test/CodeGen/LoongArch/lsx/builtin-alias.c b/clang/test/CodeGen/LoongArch/lsx/builtin-alias.c index 331e29fb7d17f7c6e836cbb2746c205d069a2afa..7a84e0ae24f950b8d898cac908d06e15474f8db8 100644 --- a/clang/test/CodeGen/LoongArch/lsx/builtin-alias.c +++ b/clang/test/CodeGen/LoongArch/lsx/builtin-alias.c @@ -5,4080 +5,5838 @@ // CHECK-LABEL: @vsll_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsll.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsll.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsll_b(v16i8 _1, v16i8 _2) { return __lsx_vsll_b(_1, _2); } // CHECK-LABEL: @vsll_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsll.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsll.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsll_h(v8i16 _1, v8i16 _2) { return __lsx_vsll_h(_1, _2); } // CHECK-LABEL: @vsll_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsll.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsll.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsll_w(v4i32 _1, v4i32 _2) { return __lsx_vsll_w(_1, _2); } // CHECK-LABEL: @vsll_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsll.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsll.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsll_d(v2i64 _1, v2i64 _2) { return __lsx_vsll_d(_1, _2); } // CHECK-LABEL: @vslli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslli_b(v16i8 _1) { return __lsx_vslli_b(_1, 1); } // CHECK-LABEL: @vslli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslli_h(v8i16 _1) { return __lsx_vslli_h(_1, 1); } // CHECK-LABEL: @vslli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslli_w(v4i32 _1) { return __lsx_vslli_w(_1, 1); } // CHECK-LABEL: @vslli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslli_d(v2i64 _1) { return __lsx_vslli_d(_1, 1); } // CHECK-LABEL: @vsra_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsra.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsra.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsra_b(v16i8 _1, v16i8 _2) { return __lsx_vsra_b(_1, _2); } // CHECK-LABEL: @vsra_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsra.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsra.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsra_h(v8i16 _1, v8i16 _2) { return __lsx_vsra_h(_1, _2); } // CHECK-LABEL: @vsra_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsra.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsra.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsra_w(v4i32 _1, v4i32 _2) { return __lsx_vsra_w(_1, _2); } // CHECK-LABEL: @vsra_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsra.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsra.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsra_d(v2i64 _1, v2i64 _2) { return __lsx_vsra_d(_1, _2); } // CHECK-LABEL: @vsrai_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrai_b(v16i8 _1) { return __lsx_vsrai_b(_1, 1); } // CHECK-LABEL: @vsrai_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrai_h(v8i16 _1) { return __lsx_vsrai_h(_1, 1); } // CHECK-LABEL: @vsrai_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrai_w(v4i32 _1) { return __lsx_vsrai_w(_1, 1); } // CHECK-LABEL: @vsrai_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrai_d(v2i64 _1) { return __lsx_vsrai_d(_1, 1); } // CHECK-LABEL: @vsrar_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrar.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrar.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrar_b(v16i8 _1, v16i8 _2) { return __lsx_vsrar_b(_1, _2); } // CHECK-LABEL: @vsrar_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrar.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrar.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrar_h(v8i16 _1, v8i16 _2) { return __lsx_vsrar_h(_1, _2); } // CHECK-LABEL: @vsrar_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrar.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrar.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrar_w(v4i32 _1, v4i32 _2) { return __lsx_vsrar_w(_1, _2); } // CHECK-LABEL: @vsrar_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrar.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrar.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrar_d(v2i64 _1, v2i64 _2) { return __lsx_vsrar_d(_1, _2); } // CHECK-LABEL: @vsrari_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrari_b(v16i8 _1) { return __lsx_vsrari_b(_1, 1); } // CHECK-LABEL: @vsrari_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrari_h(v8i16 _1) { return __lsx_vsrari_h(_1, 1); } // CHECK-LABEL: @vsrari_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrari_w(v4i32 _1) { return __lsx_vsrari_w(_1, 1); } // CHECK-LABEL: @vsrari_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrari_d(v2i64 _1) { return __lsx_vsrari_d(_1, 1); } // CHECK-LABEL: @vsrl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrl.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrl.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrl_b(v16i8 _1, v16i8 _2) { return __lsx_vsrl_b(_1, _2); } // CHECK-LABEL: @vsrl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrl.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrl.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrl_h(v8i16 _1, v8i16 _2) { return __lsx_vsrl_h(_1, _2); } // CHECK-LABEL: @vsrl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrl.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrl.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrl_w(v4i32 _1, v4i32 _2) { return __lsx_vsrl_w(_1, _2); } // CHECK-LABEL: @vsrl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrl.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrl.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrl_d(v2i64 _1, v2i64 _2) { return __lsx_vsrl_d(_1, _2); } // CHECK-LABEL: @vsrli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrli_b(v16i8 _1) { return __lsx_vsrli_b(_1, 1); } // CHECK-LABEL: @vsrli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrli_h(v8i16 _1) { return __lsx_vsrli_h(_1, 1); } // CHECK-LABEL: @vsrli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrli_w(v4i32 _1) { return __lsx_vsrli_w(_1, 1); } // CHECK-LABEL: @vsrli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrli_d(v2i64 _1) { return __lsx_vsrli_d(_1, 1); } // CHECK-LABEL: @vsrlr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlr_b(v16i8 _1, v16i8 _2) { return __lsx_vsrlr_b(_1, _2); } // CHECK-LABEL: @vsrlr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlr_h(v8i16 _1, v8i16 _2) { return __lsx_vsrlr_h(_1, _2); } // CHECK-LABEL: @vsrlr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlr_w(v4i32 _1, v4i32 _2) { return __lsx_vsrlr_w(_1, _2); } // CHECK-LABEL: @vsrlr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrlr_d(v2i64 _1, v2i64 _2) { return __lsx_vsrlr_d(_1, _2); } // CHECK-LABEL: @vsrlri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrlri_b(v16i8 _1) { return __lsx_vsrlri_b(_1, 1); } // CHECK-LABEL: @vsrlri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrlri_h(v8i16 _1) { return __lsx_vsrlri_h(_1, 1); } // CHECK-LABEL: @vsrlri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrlri_w(v4i32 _1) { return __lsx_vsrlri_w(_1, 1); } // CHECK-LABEL: @vsrlri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrlri_d(v2i64 _1) { return __lsx_vsrlri_d(_1, 1); } // CHECK-LABEL: @vbitclr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitclr_b(v16u8 _1, v16u8 _2) { return __lsx_vbitclr_b(_1, _2); } // CHECK-LABEL: @vbitclr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vbitclr_h(v8u16 _1, v8u16 _2) { return __lsx_vbitclr_h(_1, _2); } // CHECK-LABEL: @vbitclr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vbitclr_w(v4u32 _1, v4u32 _2) { return __lsx_vbitclr_w(_1, _2); } // CHECK-LABEL: @vbitclr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vbitclr_d(v2u64 _1, v2u64 _2) { return __lsx_vbitclr_d(_1, _2); } // CHECK-LABEL: @vbitclri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vbitclri_b(v16u8 _1) { return __lsx_vbitclri_b(_1, 1); } // CHECK-LABEL: @vbitclri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vbitclri_h(v8u16 _1) { return __lsx_vbitclri_h(_1, 1); } // CHECK-LABEL: @vbitclri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vbitclri_w(v4u32 _1) { return __lsx_vbitclri_w(_1, 1); } // CHECK-LABEL: @vbitclri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vbitclri_d(v2u64 _1) { return __lsx_vbitclri_d(_1, 1); } // CHECK-LABEL: @vbitset_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitset.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitset.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitset_b(v16u8 _1, v16u8 _2) { return __lsx_vbitset_b(_1, _2); } // CHECK-LABEL: @vbitset_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitset.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitset.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vbitset_h(v8u16 _1, v8u16 _2) { return __lsx_vbitset_h(_1, _2); } // CHECK-LABEL: @vbitset_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitset.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitset.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vbitset_w(v4u32 _1, v4u32 _2) { return __lsx_vbitset_w(_1, _2); } // CHECK-LABEL: @vbitset_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitset.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitset.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vbitset_d(v2u64 _1, v2u64 _2) { return __lsx_vbitset_d(_1, _2); } // CHECK-LABEL: @vbitseti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vbitseti_b(v16u8 _1) { return __lsx_vbitseti_b(_1, 1); } // CHECK-LABEL: @vbitseti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vbitseti_h(v8u16 _1) { return __lsx_vbitseti_h(_1, 1); } // CHECK-LABEL: @vbitseti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vbitseti_w(v4u32 _1) { return __lsx_vbitseti_w(_1, 1); } // CHECK-LABEL: @vbitseti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vbitseti_d(v2u64 _1) { return __lsx_vbitseti_d(_1, 1); } // CHECK-LABEL: @vbitrev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrev.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrev.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitrev_b(v16u8 _1, v16u8 _2) { return __lsx_vbitrev_b(_1, _2); } // CHECK-LABEL: @vbitrev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrev.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrev.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vbitrev_h(v8u16 _1, v8u16 _2) { return __lsx_vbitrev_h(_1, _2); } // CHECK-LABEL: @vbitrev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrev.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrev.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vbitrev_w(v4u32 _1, v4u32 _2) { return __lsx_vbitrev_w(_1, _2); } // CHECK-LABEL: @vbitrev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrev.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrev.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vbitrev_d(v2u64 _1, v2u64 _2) { return __lsx_vbitrev_d(_1, _2); } // CHECK-LABEL: @vbitrevi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vbitrevi_b(v16u8 _1) { return __lsx_vbitrevi_b(_1, 1); } // CHECK-LABEL: @vbitrevi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vbitrevi_h(v8u16 _1) { return __lsx_vbitrevi_h(_1, 1); } // CHECK-LABEL: @vbitrevi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vbitrevi_w(v4u32 _1) { return __lsx_vbitrevi_w(_1, 1); } // CHECK-LABEL: @vbitrevi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vbitrevi_d(v2u64 _1) { return __lsx_vbitrevi_d(_1, 1); } // CHECK-LABEL: @vadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vadd_b(v16i8 _1, v16i8 _2) { return __lsx_vadd_b(_1, _2); } // CHECK-LABEL: @vadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vadd_h(v8i16 _1, v8i16 _2) { return __lsx_vadd_h(_1, _2); } // CHECK-LABEL: @vadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vadd_w(v4i32 _1, v4i32 _2) { return __lsx_vadd_w(_1, _2); } // CHECK-LABEL: @vadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vadd_d(v2i64 _1, v2i64 _2) { return __lsx_vadd_d(_1, _2); } // CHECK-LABEL: @vaddi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vaddi_bu(v16i8 _1) { return __lsx_vaddi_bu(_1, 1); } // CHECK-LABEL: @vaddi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vaddi_hu(v8i16 _1) { return __lsx_vaddi_hu(_1, 1); } // CHECK-LABEL: @vaddi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vaddi_wu(v4i32 _1) { return __lsx_vaddi_wu(_1, 1); } // CHECK-LABEL: @vaddi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vaddi_du(v2i64 _1) { return __lsx_vaddi_du(_1, 1); } // CHECK-LABEL: @vsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsub.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsub.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsub_b(v16i8 _1, v16i8 _2) { return __lsx_vsub_b(_1, _2); } // CHECK-LABEL: @vsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsub.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsub.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsub_h(v8i16 _1, v8i16 _2) { return __lsx_vsub_h(_1, _2); } // CHECK-LABEL: @vsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsub_w(v4i32 _1, v4i32 _2) { return __lsx_vsub_w(_1, _2); } // CHECK-LABEL: @vsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsub_d(v2i64 _1, v2i64 _2) { return __lsx_vsub_d(_1, _2); } // CHECK-LABEL: @vsubi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsubi_bu(v16i8 _1) { return __lsx_vsubi_bu(_1, 1); } // CHECK-LABEL: @vsubi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsubi_hu(v8i16 _1) { return __lsx_vsubi_hu(_1, 1); } // CHECK-LABEL: @vsubi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsubi_wu(v4i32 _1) { return __lsx_vsubi_wu(_1, 1); } // CHECK-LABEL: @vsubi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsubi_du(v2i64 _1) { return __lsx_vsubi_du(_1, 1); } // CHECK-LABEL: @vmax_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmax_b(v16i8 _1, v16i8 _2) { return __lsx_vmax_b(_1, _2); } // CHECK-LABEL: @vmax_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmax_h(v8i16 _1, v8i16 _2) { return __lsx_vmax_h(_1, _2); } // CHECK-LABEL: @vmax_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmax_w(v4i32 _1, v4i32 _2) { return __lsx_vmax_w(_1, _2); } // CHECK-LABEL: @vmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmax_d(v2i64 _1, v2i64 _2) { return __lsx_vmax_d(_1, _2); } // CHECK-LABEL: @vmaxi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmaxi_b(v16i8 _1) { return __lsx_vmaxi_b(_1, 1); } // CHECK-LABEL: @vmaxi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vmaxi_h(v8i16 _1) { return __lsx_vmaxi_h(_1, 1); } // CHECK-LABEL: @vmaxi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vmaxi_w(v4i32 _1) { return __lsx_vmaxi_w(_1, 1); } // CHECK-LABEL: @vmaxi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vmaxi_d(v2i64 _1) { return __lsx_vmaxi_d(_1, 1); } // CHECK-LABEL: @vmax_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmax_bu(v16u8 _1, v16u8 _2) { return __lsx_vmax_bu(_1, _2); } // CHECK-LABEL: @vmax_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmax_hu(v8u16 _1, v8u16 _2) { return __lsx_vmax_hu(_1, _2); } // CHECK-LABEL: @vmax_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmax_wu(v4u32 _1, v4u32 _2) { return __lsx_vmax_wu(_1, _2); } // CHECK-LABEL: @vmax_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmax_du(v2u64 _1, v2u64 _2) { return __lsx_vmax_du(_1, _2); } // CHECK-LABEL: @vmaxi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vmaxi_bu(v16u8 _1) { return __lsx_vmaxi_bu(_1, 1); } // CHECK-LABEL: @vmaxi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vmaxi_hu(v8u16 _1) { return __lsx_vmaxi_hu(_1, 1); } // CHECK-LABEL: @vmaxi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vmaxi_wu(v4u32 _1) { return __lsx_vmaxi_wu(_1, 1); } // CHECK-LABEL: @vmaxi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vmaxi_du(v2u64 _1) { return __lsx_vmaxi_du(_1, 1); } // CHECK-LABEL: @vmin_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmin_b(v16i8 _1, v16i8 _2) { return __lsx_vmin_b(_1, _2); } // CHECK-LABEL: @vmin_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmin_h(v8i16 _1, v8i16 _2) { return __lsx_vmin_h(_1, _2); } // CHECK-LABEL: @vmin_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmin_w(v4i32 _1, v4i32 _2) { return __lsx_vmin_w(_1, _2); } // CHECK-LABEL: @vmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmin_d(v2i64 _1, v2i64 _2) { return __lsx_vmin_d(_1, _2); } // CHECK-LABEL: @vmini_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmini_b(v16i8 _1) { return __lsx_vmini_b(_1, 1); } // CHECK-LABEL: @vmini_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vmini_h(v8i16 _1) { return __lsx_vmini_h(_1, 1); } // CHECK-LABEL: @vmini_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vmini_w(v4i32 _1) { return __lsx_vmini_w(_1, 1); } // CHECK-LABEL: @vmini_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vmini_d(v2i64 _1) { return __lsx_vmini_d(_1, 1); } // CHECK-LABEL: @vmin_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmin_bu(v16u8 _1, v16u8 _2) { return __lsx_vmin_bu(_1, _2); } // CHECK-LABEL: @vmin_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmin_hu(v8u16 _1, v8u16 _2) { return __lsx_vmin_hu(_1, _2); } // CHECK-LABEL: @vmin_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmin_wu(v4u32 _1, v4u32 _2) { return __lsx_vmin_wu(_1, _2); } // CHECK-LABEL: @vmin_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmin_du(v2u64 _1, v2u64 _2) { return __lsx_vmin_du(_1, _2); } // CHECK-LABEL: @vmini_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vmini_bu(v16u8 _1) { return __lsx_vmini_bu(_1, 1); } // CHECK-LABEL: @vmini_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vmini_hu(v8u16 _1) { return __lsx_vmini_hu(_1, 1); } // CHECK-LABEL: @vmini_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vmini_wu(v4u32 _1) { return __lsx_vmini_wu(_1, 1); } // CHECK-LABEL: @vmini_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vmini_du(v2u64 _1) { return __lsx_vmini_du(_1, 1); } // CHECK-LABEL: @vseq_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseq.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseq.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vseq_b(v16i8 _1, v16i8 _2) { return __lsx_vseq_b(_1, _2); } // CHECK-LABEL: @vseq_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseq.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseq.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vseq_h(v8i16 _1, v8i16 _2) { return __lsx_vseq_h(_1, _2); } // CHECK-LABEL: @vseq_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseq.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseq.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vseq_w(v4i32 _1, v4i32 _2) { return __lsx_vseq_w(_1, _2); } // CHECK-LABEL: @vseq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseq.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseq.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vseq_d(v2i64 _1, v2i64 _2) { return __lsx_vseq_d(_1, _2); } // CHECK-LABEL: @vseqi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vseqi_b(v16i8 _1) { return __lsx_vseqi_b(_1, 1); } // CHECK-LABEL: @vseqi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vseqi_h(v8i16 _1) { return __lsx_vseqi_h(_1, 1); } // CHECK-LABEL: @vseqi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vseqi_w(v4i32 _1) { return __lsx_vseqi_w(_1, 1); } // CHECK-LABEL: @vseqi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vseqi_d(v2i64 _1) { return __lsx_vseqi_d(_1, 1); } // CHECK-LABEL: @vslti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslti_b(v16i8 _1) { return __lsx_vslti_b(_1, 1); } // CHECK-LABEL: @vslt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vslt_b(v16i8 _1, v16i8 _2) { return __lsx_vslt_b(_1, _2); } // CHECK-LABEL: @vslt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vslt_h(v8i16 _1, v8i16 _2) { return __lsx_vslt_h(_1, _2); } // CHECK-LABEL: @vslt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vslt_w(v4i32 _1, v4i32 _2) { return __lsx_vslt_w(_1, _2); } // CHECK-LABEL: @vslt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vslt_d(v2i64 _1, v2i64 _2) { return __lsx_vslt_d(_1, _2); } // CHECK-LABEL: @vslti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslti_h(v8i16 _1) { return __lsx_vslti_h(_1, 1); } // CHECK-LABEL: @vslti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslti_w(v4i32 _1) { return __lsx_vslti_w(_1, 1); } // CHECK-LABEL: @vslti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslti_d(v2i64 _1) { return __lsx_vslti_d(_1, 1); } // CHECK-LABEL: @vslt_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vslt_bu(v16u8 _1, v16u8 _2) { return __lsx_vslt_bu(_1, _2); } // CHECK-LABEL: @vslt_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vslt_hu(v8u16 _1, v8u16 _2) { return __lsx_vslt_hu(_1, _2); } // CHECK-LABEL: @vslt_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vslt_wu(v4u32 _1, v4u32 _2) { return __lsx_vslt_wu(_1, _2); } // CHECK-LABEL: @vslt_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vslt_du(v2u64 _1, v2u64 _2) { return __lsx_vslt_du(_1, _2); } // CHECK-LABEL: @vslti_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslti_bu(v16u8 _1) { return __lsx_vslti_bu(_1, 1); } // CHECK-LABEL: @vslti_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslti_hu(v8u16 _1) { return __lsx_vslti_hu(_1, 1); } // CHECK-LABEL: @vslti_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslti_wu(v4u32 _1) { return __lsx_vslti_wu(_1, 1); } // CHECK-LABEL: @vslti_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslti_du(v2u64 _1) { return __lsx_vslti_du(_1, 1); } // CHECK-LABEL: @vsle_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsle_b(v16i8 _1, v16i8 _2) { return __lsx_vsle_b(_1, _2); } // CHECK-LABEL: @vsle_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsle_h(v8i16 _1, v8i16 _2) { return __lsx_vsle_h(_1, _2); } // CHECK-LABEL: @vsle_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsle_w(v4i32 _1, v4i32 _2) { return __lsx_vsle_w(_1, _2); } // CHECK-LABEL: @vsle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsle_d(v2i64 _1, v2i64 _2) { return __lsx_vsle_d(_1, _2); } // CHECK-LABEL: @vslei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslei_b(v16i8 _1) { return __lsx_vslei_b(_1, 1); } // CHECK-LABEL: @vslei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslei_h(v8i16 _1) { return __lsx_vslei_h(_1, 1); } // CHECK-LABEL: @vslei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslei_w(v4i32 _1) { return __lsx_vslei_w(_1, 1); } // CHECK-LABEL: @vslei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslei_d(v2i64 _1) { return __lsx_vslei_d(_1, 1); } // CHECK-LABEL: @vsle_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsle_bu(v16u8 _1, v16u8 _2) { return __lsx_vsle_bu(_1, _2); } // CHECK-LABEL: @vsle_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsle_hu(v8u16 _1, v8u16 _2) { return __lsx_vsle_hu(_1, _2); } // CHECK-LABEL: @vsle_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsle_wu(v4u32 _1, v4u32 _2) { return __lsx_vsle_wu(_1, _2); } // CHECK-LABEL: @vsle_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsle_du(v2u64 _1, v2u64 _2) { return __lsx_vsle_du(_1, _2); } // CHECK-LABEL: @vslei_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslei_bu(v16u8 _1) { return __lsx_vslei_bu(_1, 1); } // CHECK-LABEL: @vslei_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslei_hu(v8u16 _1) { return __lsx_vslei_hu(_1, 1); } // CHECK-LABEL: @vslei_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslei_wu(v4u32 _1) { return __lsx_vslei_wu(_1, 1); } // CHECK-LABEL: @vslei_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslei_du(v2u64 _1) { return __lsx_vslei_du(_1, 1); } // CHECK-LABEL: @vsat_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsat_b(v16i8 _1) { return __lsx_vsat_b(_1, 1); } // CHECK-LABEL: @vsat_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsat_h(v8i16 _1) { return __lsx_vsat_h(_1, 1); } // CHECK-LABEL: @vsat_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsat_w(v4i32 _1) { return __lsx_vsat_w(_1, 1); } // CHECK-LABEL: @vsat_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsat_d(v2i64 _1) { return __lsx_vsat_d(_1, 1); } // CHECK-LABEL: @vsat_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vsat_bu(v16u8 _1) { return __lsx_vsat_bu(_1, 1); } // CHECK-LABEL: @vsat_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vsat_hu(v8u16 _1) { return __lsx_vsat_hu(_1, 1); } // CHECK-LABEL: @vsat_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vsat_wu(v4u32 _1) { return __lsx_vsat_wu(_1, 1); } // CHECK-LABEL: @vsat_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vsat_du(v2u64 _1) { return __lsx_vsat_du(_1, 1); } // CHECK-LABEL: @vadda_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadda.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadda.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vadda_b(v16i8 _1, v16i8 _2) { return __lsx_vadda_b(_1, _2); } // CHECK-LABEL: @vadda_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadda.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadda.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vadda_h(v8i16 _1, v8i16 _2) { return __lsx_vadda_h(_1, _2); } // CHECK-LABEL: @vadda_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadda.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadda.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vadda_w(v4i32 _1, v4i32 _2) { return __lsx_vadda_w(_1, _2); } // CHECK-LABEL: @vadda_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadda.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadda.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vadda_d(v2i64 _1, v2i64 _2) { return __lsx_vadda_d(_1, _2); } // CHECK-LABEL: @vsadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsadd_b(v16i8 _1, v16i8 _2) { return __lsx_vsadd_b(_1, _2); } // CHECK-LABEL: @vsadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsadd_h(v8i16 _1, v8i16 _2) { return __lsx_vsadd_h(_1, _2); } // CHECK-LABEL: @vsadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsadd_w(v4i32 _1, v4i32 _2) { return __lsx_vsadd_w(_1, _2); } // CHECK-LABEL: @vsadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsadd_d(v2i64 _1, v2i64 _2) { return __lsx_vsadd_d(_1, _2); } // CHECK-LABEL: @vsadd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vsadd_bu(v16u8 _1, v16u8 _2) { return __lsx_vsadd_bu(_1, _2); } // CHECK-LABEL: @vsadd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vsadd_hu(v8u16 _1, v8u16 _2) { return __lsx_vsadd_hu(_1, _2); } // CHECK-LABEL: @vsadd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vsadd_wu(v4u32 _1, v4u32 _2) { return __lsx_vsadd_wu(_1, _2); } // CHECK-LABEL: @vsadd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vsadd_du(v2u64 _1, v2u64 _2) { return __lsx_vsadd_du(_1, _2); } // CHECK-LABEL: @vavg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vavg_b(v16i8 _1, v16i8 _2) { return __lsx_vavg_b(_1, _2); } // CHECK-LABEL: @vavg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vavg_h(v8i16 _1, v8i16 _2) { return __lsx_vavg_h(_1, _2); } // CHECK-LABEL: @vavg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vavg_w(v4i32 _1, v4i32 _2) { return __lsx_vavg_w(_1, _2); } // CHECK-LABEL: @vavg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vavg_d(v2i64 _1, v2i64 _2) { return __lsx_vavg_d(_1, _2); } // CHECK-LABEL: @vavg_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vavg_bu(v16u8 _1, v16u8 _2) { return __lsx_vavg_bu(_1, _2); } // CHECK-LABEL: @vavg_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vavg_hu(v8u16 _1, v8u16 _2) { return __lsx_vavg_hu(_1, _2); } // CHECK-LABEL: @vavg_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vavg_wu(v4u32 _1, v4u32 _2) { return __lsx_vavg_wu(_1, _2); } // CHECK-LABEL: @vavg_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vavg_du(v2u64 _1, v2u64 _2) { return __lsx_vavg_du(_1, _2); } // CHECK-LABEL: @vavgr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vavgr_b(v16i8 _1, v16i8 _2) { return __lsx_vavgr_b(_1, _2); } // CHECK-LABEL: @vavgr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vavgr_h(v8i16 _1, v8i16 _2) { return __lsx_vavgr_h(_1, _2); } // CHECK-LABEL: @vavgr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vavgr_w(v4i32 _1, v4i32 _2) { return __lsx_vavgr_w(_1, _2); } // CHECK-LABEL: @vavgr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vavgr_d(v2i64 _1, v2i64 _2) { return __lsx_vavgr_d(_1, _2); } // CHECK-LABEL: @vavgr_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vavgr_bu(v16u8 _1, v16u8 _2) { return __lsx_vavgr_bu(_1, _2); } // CHECK-LABEL: @vavgr_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vavgr_hu(v8u16 _1, v8u16 _2) { return __lsx_vavgr_hu(_1, _2); } // CHECK-LABEL: @vavgr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vavgr_wu(v4u32 _1, v4u32 _2) { return __lsx_vavgr_wu(_1, _2); } // CHECK-LABEL: @vavgr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vavgr_du(v2u64 _1, v2u64 _2) { return __lsx_vavgr_du(_1, _2); } // CHECK-LABEL: @vssub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssub_b(v16i8 _1, v16i8 _2) { return __lsx_vssub_b(_1, _2); } // CHECK-LABEL: @vssub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssub_h(v8i16 _1, v8i16 _2) { return __lsx_vssub_h(_1, _2); } // CHECK-LABEL: @vssub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssub_w(v4i32 _1, v4i32 _2) { return __lsx_vssub_w(_1, _2); } // CHECK-LABEL: @vssub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssub_d(v2i64 _1, v2i64 _2) { return __lsx_vssub_d(_1, _2); } // CHECK-LABEL: @vssub_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssub_bu(v16u8 _1, v16u8 _2) { return __lsx_vssub_bu(_1, _2); } // CHECK-LABEL: @vssub_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssub_hu(v8u16 _1, v8u16 _2) { return __lsx_vssub_hu(_1, _2); } // CHECK-LABEL: @vssub_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssub_wu(v4u32 _1, v4u32 _2) { return __lsx_vssub_wu(_1, _2); } // CHECK-LABEL: @vssub_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssub_du(v2u64 _1, v2u64 _2) { return __lsx_vssub_du(_1, _2); } // CHECK-LABEL: @vabsd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vabsd_b(v16i8 _1, v16i8 _2) { return __lsx_vabsd_b(_1, _2); } // CHECK-LABEL: @vabsd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vabsd_h(v8i16 _1, v8i16 _2) { return __lsx_vabsd_h(_1, _2); } // CHECK-LABEL: @vabsd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vabsd_w(v4i32 _1, v4i32 _2) { return __lsx_vabsd_w(_1, _2); } // CHECK-LABEL: @vabsd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vabsd_d(v2i64 _1, v2i64 _2) { return __lsx_vabsd_d(_1, _2); } // CHECK-LABEL: @vabsd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vabsd_bu(v16u8 _1, v16u8 _2) { return __lsx_vabsd_bu(_1, _2); } // CHECK-LABEL: @vabsd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vabsd_hu(v8u16 _1, v8u16 _2) { return __lsx_vabsd_hu(_1, _2); } // CHECK-LABEL: @vabsd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vabsd_wu(v4u32 _1, v4u32 _2) { return __lsx_vabsd_wu(_1, _2); } // CHECK-LABEL: @vabsd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vabsd_du(v2u64 _1, v2u64 _2) { return __lsx_vabsd_du(_1, _2); } // CHECK-LABEL: @vmul_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmul.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmul.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmul_b(v16i8 _1, v16i8 _2) { return __lsx_vmul_b(_1, _2); } // CHECK-LABEL: @vmul_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmul.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmul.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmul_h(v8i16 _1, v8i16 _2) { return __lsx_vmul_h(_1, _2); } // CHECK-LABEL: @vmul_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmul.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmul.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmul_w(v4i32 _1, v4i32 _2) { return __lsx_vmul_w(_1, _2); } // CHECK-LABEL: @vmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmul.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmul.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmul_d(v2i64 _1, v2i64 _2) { return __lsx_vmul_d(_1, _2); } // CHECK-LABEL: @vmadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmadd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmadd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vmadd_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __lsx_vmadd_b(_1, _2, _3); } // CHECK-LABEL: @vmadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmadd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmadd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmadd_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __lsx_vmadd_h(_1, _2, _3); } // CHECK-LABEL: @vmadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmadd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmadd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmadd_w(v4i32 _1, v4i32 _2, v4i32 _3) { return __lsx_vmadd_w(_1, _2, _3); } // CHECK-LABEL: @vmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmadd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmadd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmadd_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __lsx_vmadd_d(_1, _2, _3); } // CHECK-LABEL: @vmsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsub.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsub.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vmsub_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __lsx_vmsub_b(_1, _2, _3); } // CHECK-LABEL: @vmsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmsub.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmsub.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmsub_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __lsx_vmsub_h(_1, _2, _3); } // CHECK-LABEL: @vmsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmsub.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmsub.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmsub_w(v4i32 _1, v4i32 _2, v4i32 _3) { return __lsx_vmsub_w(_1, _2, _3); } // CHECK-LABEL: @vmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmsub.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmsub.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmsub_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __lsx_vmsub_d(_1, _2, _3); } // CHECK-LABEL: @vdiv_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vdiv_b(v16i8 _1, v16i8 _2) { return __lsx_vdiv_b(_1, _2); } // CHECK-LABEL: @vdiv_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vdiv_h(v8i16 _1, v8i16 _2) { return __lsx_vdiv_h(_1, _2); } // CHECK-LABEL: @vdiv_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vdiv_w(v4i32 _1, v4i32 _2) { return __lsx_vdiv_w(_1, _2); } // CHECK-LABEL: @vdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vdiv_d(v2i64 _1, v2i64 _2) { return __lsx_vdiv_d(_1, _2); } // CHECK-LABEL: @vdiv_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vdiv_bu(v16u8 _1, v16u8 _2) { return __lsx_vdiv_bu(_1, _2); } // CHECK-LABEL: @vdiv_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vdiv_hu(v8u16 _1, v8u16 _2) { return __lsx_vdiv_hu(_1, _2); } // CHECK-LABEL: @vdiv_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vdiv_wu(v4u32 _1, v4u32 _2) { return __lsx_vdiv_wu(_1, _2); } // CHECK-LABEL: @vdiv_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vdiv_du(v2u64 _1, v2u64 _2) { return __lsx_vdiv_du(_1, _2); } // CHECK-LABEL: @vhaddw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vhaddw_h_b(v16i8 _1, v16i8 _2) { return __lsx_vhaddw_h_b(_1, _2); } // CHECK-LABEL: @vhaddw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vhaddw_w_h(v8i16 _1, v8i16 _2) { return __lsx_vhaddw_w_h(_1, _2); } // CHECK-LABEL: @vhaddw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhaddw_d_w(v4i32 _1, v4i32 _2) { return __lsx_vhaddw_d_w(_1, _2); } // CHECK-LABEL: @vhaddw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.hu.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.hu.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vhaddw_hu_bu(v16u8 _1, v16u8 _2) { return __lsx_vhaddw_hu_bu(_1, _2); } // CHECK-LABEL: @vhaddw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.wu.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.wu.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vhaddw_wu_hu(v8u16 _1, v8u16 _2) { return __lsx_vhaddw_wu_hu(_1, _2); } // CHECK-LABEL: @vhaddw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.du.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.du.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vhaddw_du_wu(v4u32 _1, v4u32 _2) { return __lsx_vhaddw_du_wu(_1, _2); } // CHECK-LABEL: @vhsubw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vhsubw_h_b(v16i8 _1, v16i8 _2) { return __lsx_vhsubw_h_b(_1, _2); } // CHECK-LABEL: @vhsubw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vhsubw_w_h(v8i16 _1, v8i16 _2) { return __lsx_vhsubw_w_h(_1, _2); } // CHECK-LABEL: @vhsubw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhsubw_d_w(v4i32 _1, v4i32 _2) { return __lsx_vhsubw_d_w(_1, _2); } // CHECK-LABEL: @vhsubw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.hu.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.hu.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vhsubw_hu_bu(v16u8 _1, v16u8 _2) { return __lsx_vhsubw_hu_bu(_1, _2); } // CHECK-LABEL: @vhsubw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.wu.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.wu.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vhsubw_wu_hu(v8u16 _1, v8u16 _2) { return __lsx_vhsubw_wu_hu(_1, _2); } // CHECK-LABEL: @vhsubw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.du.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.du.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhsubw_du_wu(v4u32 _1, v4u32 _2) { return __lsx_vhsubw_du_wu(_1, _2); } // CHECK-LABEL: @vmod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmod_b(v16i8 _1, v16i8 _2) { return __lsx_vmod_b(_1, _2); } // CHECK-LABEL: @vmod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmod_h(v8i16 _1, v8i16 _2) { return __lsx_vmod_h(_1, _2); } // CHECK-LABEL: @vmod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmod_w(v4i32 _1, v4i32 _2) { return __lsx_vmod_w(_1, _2); } // CHECK-LABEL: @vmod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmod_d(v2i64 _1, v2i64 _2) { return __lsx_vmod_d(_1, _2); } // CHECK-LABEL: @vmod_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmod_bu(v16u8 _1, v16u8 _2) { return __lsx_vmod_bu(_1, _2); } // CHECK-LABEL: @vmod_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmod_hu(v8u16 _1, v8u16 _2) { return __lsx_vmod_hu(_1, _2); } // CHECK-LABEL: @vmod_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmod_wu(v4u32 _1, v4u32 _2) { return __lsx_vmod_wu(_1, _2); } // CHECK-LABEL: @vmod_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmod_du(v2u64 _1, v2u64 _2) { return __lsx_vmod_du(_1, _2); } // CHECK-LABEL: @vreplve_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplve.b(<16 x i8> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplve.b(<16 x i8> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vreplve_b(v16i8 _1, int _2) { return __lsx_vreplve_b(_1, _2); } // CHECK-LABEL: @vreplve_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplve.h(<8 x i16> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplve.h(<8 x i16> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vreplve_h(v8i16 _1, int _2) { return __lsx_vreplve_h(_1, _2); } // CHECK-LABEL: @vreplve_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplve.w(<4 x i32> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplve.w(<4 x i32> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vreplve_w(v4i32 _1, int _2) { return __lsx_vreplve_w(_1, _2); } // CHECK-LABEL: @vreplve_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplve.d(<2 x i64> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplve.d(<2 x i64> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vreplve_d(v2i64 _1, int _2) { return __lsx_vreplve_d(_1, _2); } // CHECK-LABEL: @vreplvei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vreplvei_b(v16i8 _1) { return __lsx_vreplvei_b(_1, 1); } // CHECK-LABEL: @vreplvei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vreplvei_h(v8i16 _1) { return __lsx_vreplvei_h(_1, 1); } // CHECK-LABEL: @vreplvei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vreplvei_w(v4i32 _1) { return __lsx_vreplvei_w(_1, 1); } // CHECK-LABEL: @vreplvei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vreplvei_d(v2i64 _1) { return __lsx_vreplvei_d(_1, 1); } // CHECK-LABEL: @vpickev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickev.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickev.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpickev_b(v16i8 _1, v16i8 _2) { return __lsx_vpickev_b(_1, _2); } // CHECK-LABEL: @vpickev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickev.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickev.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpickev_h(v8i16 _1, v8i16 _2) { return __lsx_vpickev_h(_1, _2); } // CHECK-LABEL: @vpickev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickev.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickev.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpickev_w(v4i32 _1, v4i32 _2) { return __lsx_vpickev_w(_1, _2); } // CHECK-LABEL: @vpickev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickev.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickev.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpickev_d(v2i64 _1, v2i64 _2) { return __lsx_vpickev_d(_1, _2); } // CHECK-LABEL: @vpickod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickod.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickod.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpickod_b(v16i8 _1, v16i8 _2) { return __lsx_vpickod_b(_1, _2); } // CHECK-LABEL: @vpickod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickod.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickod.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpickod_h(v8i16 _1, v8i16 _2) { return __lsx_vpickod_h(_1, _2); } // CHECK-LABEL: @vpickod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickod.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickod.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpickod_w(v4i32 _1, v4i32 _2) { return __lsx_vpickod_w(_1, _2); } // CHECK-LABEL: @vpickod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickod.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickod.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpickod_d(v2i64 _1, v2i64 _2) { return __lsx_vpickod_d(_1, _2); } // CHECK-LABEL: @vilvh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvh.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvh.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vilvh_b(v16i8 _1, v16i8 _2) { return __lsx_vilvh_b(_1, _2); } // CHECK-LABEL: @vilvh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvh.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvh.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vilvh_h(v8i16 _1, v8i16 _2) { return __lsx_vilvh_h(_1, _2); } // CHECK-LABEL: @vilvh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvh.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvh.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vilvh_w(v4i32 _1, v4i32 _2) { return __lsx_vilvh_w(_1, _2); } // CHECK-LABEL: @vilvh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvh.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvh.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vilvh_d(v2i64 _1, v2i64 _2) { return __lsx_vilvh_d(_1, _2); } // CHECK-LABEL: @vilvl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvl.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvl.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vilvl_b(v16i8 _1, v16i8 _2) { return __lsx_vilvl_b(_1, _2); } // CHECK-LABEL: @vilvl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvl.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvl.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vilvl_h(v8i16 _1, v8i16 _2) { return __lsx_vilvl_h(_1, _2); } // CHECK-LABEL: @vilvl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvl.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvl.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vilvl_w(v4i32 _1, v4i32 _2) { return __lsx_vilvl_w(_1, _2); } // CHECK-LABEL: @vilvl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvl.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvl.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vilvl_d(v2i64 _1, v2i64 _2) { return __lsx_vilvl_d(_1, _2); } // CHECK-LABEL: @vpackev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackev.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackev.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpackev_b(v16i8 _1, v16i8 _2) { return __lsx_vpackev_b(_1, _2); } // CHECK-LABEL: @vpackev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackev.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackev.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpackev_h(v8i16 _1, v8i16 _2) { return __lsx_vpackev_h(_1, _2); } // CHECK-LABEL: @vpackev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackev.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackev.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpackev_w(v4i32 _1, v4i32 _2) { return __lsx_vpackev_w(_1, _2); } // CHECK-LABEL: @vpackev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackev.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackev.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpackev_d(v2i64 _1, v2i64 _2) { return __lsx_vpackev_d(_1, _2); } // CHECK-LABEL: @vpackod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackod.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackod.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpackod_b(v16i8 _1, v16i8 _2) { return __lsx_vpackod_b(_1, _2); } // CHECK-LABEL: @vpackod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackod.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackod.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpackod_h(v8i16 _1, v8i16 _2) { return __lsx_vpackod_h(_1, _2); } // CHECK-LABEL: @vpackod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackod.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackod.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpackod_w(v4i32 _1, v4i32 _2) { return __lsx_vpackod_w(_1, _2); } // CHECK-LABEL: @vpackod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackod.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackod.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpackod_d(v2i64 _1, v2i64 _2) { return __lsx_vpackod_d(_1, _2); } // CHECK-LABEL: @vshuf_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vshuf_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __lsx_vshuf_h(_1, _2, _3); } // CHECK-LABEL: @vshuf_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vshuf_w(v4i32 _1, v4i32 _2, v4i32 _3) { return __lsx_vshuf_w(_1, _2, _3); } // CHECK-LABEL: @vshuf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vshuf_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __lsx_vshuf_d(_1, _2, _3); } // CHECK-LABEL: @vand_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vand.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vand.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vand_v(v16u8 _1, v16u8 _2) { return __lsx_vand_v(_1, _2); } // CHECK-LABEL: @vandi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vandi_b(v16u8 _1) { return __lsx_vandi_b(_1, 1); } // CHECK-LABEL: @vor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vor.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vor.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vor_v(v16u8 _1, v16u8 _2) { return __lsx_vor_v(_1, _2); } // CHECK-LABEL: @vori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vori_b(v16u8 _1) { return __lsx_vori_b(_1, 1); } // CHECK-LABEL: @vnor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnor.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnor.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vnor_v(v16u8 _1, v16u8 _2) { return __lsx_vnor_v(_1, _2); } // CHECK-LABEL: @vnori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vnori_b(v16u8 _1) { return __lsx_vnori_b(_1, 1); } // CHECK-LABEL: @vxor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxor.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxor.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vxor_v(v16u8 _1, v16u8 _2) { return __lsx_vxor_v(_1, _2); } // CHECK-LABEL: @vxori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vxori_b(v16u8 _1) { return __lsx_vxori_b(_1, 1); } // CHECK-LABEL: @vbitsel_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitsel.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitsel.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16u8 vbitsel_v(v16u8 _1, v16u8 _2, v16u8 _3) { return __lsx_vbitsel_v(_1, _2, _3); } // CHECK-LABEL: @vbitseli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitseli_b(v16u8 _1, v16u8 _2) { return __lsx_vbitseli_b(_1, _2, 1); } // CHECK-LABEL: @vshuf4i_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vshuf4i_b(v16i8 _1) { return __lsx_vshuf4i_b(_1, 1); } // CHECK-LABEL: @vshuf4i_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vshuf4i_h(v8i16 _1) { return __lsx_vshuf4i_h(_1, 1); } // CHECK-LABEL: @vshuf4i_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vshuf4i_w(v4i32 _1) { return __lsx_vshuf4i_w(_1, 1); } // CHECK-LABEL: @vreplgr2vr_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplgr2vr.b(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vreplgr2vr_b(int _1) { return __lsx_vreplgr2vr_b(_1); } // CHECK-LABEL: @vreplgr2vr_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplgr2vr.h(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v8i16 vreplgr2vr_h(int _1) { return __lsx_vreplgr2vr_h(_1); } // CHECK-LABEL: @vreplgr2vr_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplgr2vr.w(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v4i32 vreplgr2vr_w(int _1) { return __lsx_vreplgr2vr_w(_1); } // CHECK-LABEL: @vreplgr2vr_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplgr2vr.d(i64 [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vreplgr2vr_d(long _1) { return __lsx_vreplgr2vr_d(_1); } // CHECK-LABEL: @vpcnt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpcnt.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpcnt.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vpcnt_b(v16i8 _1) { return __lsx_vpcnt_b(_1); } // CHECK-LABEL: @vpcnt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpcnt.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpcnt.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vpcnt_h(v8i16 _1) { return __lsx_vpcnt_h(_1); } // CHECK-LABEL: @vpcnt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpcnt.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpcnt.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vpcnt_w(v4i32 _1) { return __lsx_vpcnt_w(_1); } // CHECK-LABEL: @vpcnt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpcnt.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpcnt.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vpcnt_d(v2i64 _1) { return __lsx_vpcnt_d(_1); } // CHECK-LABEL: @vclo_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclo.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclo.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vclo_b(v16i8 _1) { return __lsx_vclo_b(_1); } // CHECK-LABEL: @vclo_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclo.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclo.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vclo_h(v8i16 _1) { return __lsx_vclo_h(_1); } // CHECK-LABEL: @vclo_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclo.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclo.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vclo_w(v4i32 _1) { return __lsx_vclo_w(_1); } // CHECK-LABEL: @vclo_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclo.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclo.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vclo_d(v2i64 _1) { return __lsx_vclo_d(_1); } // CHECK-LABEL: @vclz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vclz_b(v16i8 _1) { return __lsx_vclz_b(_1); } // CHECK-LABEL: @vclz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vclz_h(v8i16 _1) { return __lsx_vclz_h(_1); } // CHECK-LABEL: @vclz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vclz_w(v4i32 _1) { return __lsx_vclz_w(_1); } // CHECK-LABEL: @vclz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vclz_d(v2i64 _1) { return __lsx_vclz_d(_1); } // CHECK-LABEL: @vpickve2gr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int vpickve2gr_b(v16i8 _1) { return __lsx_vpickve2gr_b(_1, 1); } // CHECK-LABEL: @vpickve2gr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int vpickve2gr_h(v8i16 _1) { return __lsx_vpickve2gr_h(_1, 1); } // CHECK-LABEL: @vpickve2gr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int vpickve2gr_w(v4i32 _1) { return __lsx_vpickve2gr_w(_1, 1); } // CHECK-LABEL: @vpickve2gr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // long vpickve2gr_d(v2i64 _1) { return __lsx_vpickve2gr_d(_1, 1); } // CHECK-LABEL: @vpickve2gr_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int vpickve2gr_bu(v16i8 _1) { return __lsx_vpickve2gr_bu(_1, 1); } // CHECK-LABEL: @vpickve2gr_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int vpickve2gr_hu(v8i16 _1) { return __lsx_vpickve2gr_hu(_1, 1); } // CHECK-LABEL: @vpickve2gr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int vpickve2gr_wu(v4i32 _1) { return __lsx_vpickve2gr_wu(_1, 1); } // CHECK-LABEL: @vpickve2gr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // unsigned long int vpickve2gr_du(v2i64 _1) { return __lsx_vpickve2gr_du(_1, 1); } // CHECK-LABEL: @vinsgr2vr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> [[TMP0]], i32 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vinsgr2vr_b(v16i8 _1) { return __lsx_vinsgr2vr_b(_1, 1, 1); } // CHECK-LABEL: @vinsgr2vr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> [[TMP0]], i32 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vinsgr2vr_h(v8i16 _1) { return __lsx_vinsgr2vr_h(_1, 1, 1); } // CHECK-LABEL: @vinsgr2vr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> [[TMP0]], i32 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vinsgr2vr_w(v4i32 _1) { return __lsx_vinsgr2vr_w(_1, 1, 1); } // CHECK-LABEL: @vinsgr2vr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> [[_1:%.*]], i64 1, i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> [[TMP0]], i64 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vinsgr2vr_d(v2i64 _1) { return __lsx_vinsgr2vr_d(_1, 1, 1); } // CHECK-LABEL: @vfadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfadd.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfadd.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfadd_s(v4f32 _1, v4f32 _2) { return __lsx_vfadd_s(_1, _2); } // CHECK-LABEL: @vfadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfadd.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfadd.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfadd_d(v2f64 _1, v2f64 _2) { return __lsx_vfadd_d(_1, _2); } // CHECK-LABEL: @vfsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsub.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsub.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfsub_s(v4f32 _1, v4f32 _2) { return __lsx_vfsub_s(_1, _2); } // CHECK-LABEL: @vfsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsub.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsub.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfsub_d(v2f64 _1, v2f64 _2) { return __lsx_vfsub_d(_1, _2); } // CHECK-LABEL: @vfmul_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmul.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmul.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmul_s(v4f32 _1, v4f32 _2) { return __lsx_vfmul_s(_1, _2); } // CHECK-LABEL: @vfmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmul.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmul.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmul_d(v2f64 _1, v2f64 _2) { return __lsx_vfmul_d(_1, _2); } // CHECK-LABEL: @vfdiv_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfdiv.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfdiv.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfdiv_s(v4f32 _1, v4f32 _2) { return __lsx_vfdiv_s(_1, _2); } // CHECK-LABEL: @vfdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfdiv.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfdiv.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfdiv_d(v2f64 _1, v2f64 _2) { return __lsx_vfdiv_d(_1, _2); } // CHECK-LABEL: @vfcvt_h_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfcvt.h.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfcvt.h.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vfcvt_h_s(v4f32 _1, v4f32 _2) { return __lsx_vfcvt_h_s(_1, _2); } // CHECK-LABEL: @vfcvt_s_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvt.s.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvt.s.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfcvt_s_d(v2f64 _1, v2f64 _2) { return __lsx_vfcvt_s_d(_1, _2); } // CHECK-LABEL: @vfmin_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmin.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmin.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmin_s(v4f32 _1, v4f32 _2) { return __lsx_vfmin_s(_1, _2); } // CHECK-LABEL: @vfmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmin.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmin.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmin_d(v2f64 _1, v2f64 _2) { return __lsx_vfmin_d(_1, _2); } // CHECK-LABEL: @vfmina_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmina.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmina.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmina_s(v4f32 _1, v4f32 _2) { return __lsx_vfmina_s(_1, _2); } // CHECK-LABEL: @vfmina_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmina.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmina.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmina_d(v2f64 _1, v2f64 _2) { return __lsx_vfmina_d(_1, _2); } // CHECK-LABEL: @vfmax_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmax.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmax.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmax_s(v4f32 _1, v4f32 _2) { return __lsx_vfmax_s(_1, _2); } // CHECK-LABEL: @vfmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmax.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmax.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmax_d(v2f64 _1, v2f64 _2) { return __lsx_vfmax_d(_1, _2); } // CHECK-LABEL: @vfmaxa_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmaxa.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmaxa.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmaxa_s(v4f32 _1, v4f32 _2) { return __lsx_vfmaxa_s(_1, _2); } // CHECK-LABEL: @vfmaxa_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmaxa.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmaxa.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmaxa_d(v2f64 _1, v2f64 _2) { return __lsx_vfmaxa_d(_1, _2); } // CHECK-LABEL: @vfclass_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfclass.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfclass.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfclass_s(v4f32 _1) { return __lsx_vfclass_s(_1); } // CHECK-LABEL: @vfclass_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfclass.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfclass.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfclass_d(v2f64 _1) { return __lsx_vfclass_d(_1); } // CHECK-LABEL: @vfsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsqrt.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsqrt.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfsqrt_s(v4f32 _1) { return __lsx_vfsqrt_s(_1); } // CHECK-LABEL: @vfsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsqrt.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsqrt.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfsqrt_d(v2f64 _1) { return __lsx_vfsqrt_d(_1); } // CHECK-LABEL: @vfrecip_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrecip.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrecip.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfrecip_s(v4f32 _1) { return __lsx_vfrecip_s(_1); } // CHECK-LABEL: @vfrecip_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrecip.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrecip.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfrecip_d(v2f64 _1) { return __lsx_vfrecip_d(_1); } // CHECK-LABEL: @vfrint_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrint.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrint.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfrint_s(v4f32 _1) { return __lsx_vfrint_s(_1); } // CHECK-LABEL: @vfrint_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrint.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrint.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfrint_d(v2f64 _1) { return __lsx_vfrint_d(_1); } // CHECK-LABEL: @vfrsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrsqrt.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrsqrt.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfrsqrt_s(v4f32 _1) { return __lsx_vfrsqrt_s(_1); } // CHECK-LABEL: @vfrsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrsqrt.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrsqrt.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfrsqrt_d(v2f64 _1) { return __lsx_vfrsqrt_d(_1); } // CHECK-LABEL: @vflogb_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vflogb.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vflogb.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vflogb_s(v4f32 _1) { return __lsx_vflogb_s(_1); } // CHECK-LABEL: @vflogb_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vflogb.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vflogb.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vflogb_d(v2f64 _1) { return __lsx_vflogb_d(_1); } // CHECK-LABEL: @vfcvth_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvth.s.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvth.s.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfcvth_s_h(v8i16 _1) { return __lsx_vfcvth_s_h(_1); } // CHECK-LABEL: @vfcvth_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvth.d.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvth.d.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfcvth_d_s(v4f32 _1) { return __lsx_vfcvth_d_s(_1); } // CHECK-LABEL: @vfcvtl_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvtl.s.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvtl.s.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfcvtl_s_h(v8i16 _1) { return __lsx_vfcvtl_s_h(_1); } // CHECK-LABEL: @vfcvtl_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvtl.d.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvtl.d.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfcvtl_d_s(v4f32 _1) { return __lsx_vfcvtl_d_s(_1); } // CHECK-LABEL: @vftint_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftint_w_s(v4f32 _1) { return __lsx_vftint_w_s(_1); } // CHECK-LABEL: @vftint_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftint_l_d(v2f64 _1) { return __lsx_vftint_l_d(_1); } // CHECK-LABEL: @vftint_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.wu.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.wu.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vftint_wu_s(v4f32 _1) { return __lsx_vftint_wu_s(_1); } // CHECK-LABEL: @vftint_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.lu.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.lu.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vftint_lu_d(v2f64 _1) { return __lsx_vftint_lu_d(_1); } // CHECK-LABEL: @vftintrz_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrz_w_s(v4f32 _1) { return __lsx_vftintrz_w_s(_1); } // CHECK-LABEL: @vftintrz_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrz_l_d(v2f64 _1) { return __lsx_vftintrz_l_d(_1); } // CHECK-LABEL: @vftintrz_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.wu.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.wu.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vftintrz_wu_s(v4f32 _1) { return __lsx_vftintrz_wu_s(_1); } // CHECK-LABEL: @vftintrz_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.lu.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.lu.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vftintrz_lu_d(v2f64 _1) { return __lsx_vftintrz_lu_d(_1); } // CHECK-LABEL: @vffint_s_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vffint_s_w(v4i32 _1) { return __lsx_vffint_s_w(_1); } // CHECK-LABEL: @vffint_d_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.l(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.l(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffint_d_l(v2i64 _1) { return __lsx_vffint_d_l(_1); } // CHECK-LABEL: @vffint_s_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.wu(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.wu(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vffint_s_wu(v4u32 _1) { return __lsx_vffint_s_wu(_1); } // CHECK-LABEL: @vffint_d_lu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.lu(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.lu(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffint_d_lu(v2u64 _1) { return __lsx_vffint_d_lu(_1); } // CHECK-LABEL: @vandn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandn.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandn.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vandn_v(v16u8 _1, v16u8 _2) { return __lsx_vandn_v(_1, _2); } // CHECK-LABEL: @vneg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vneg.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vneg.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vneg_b(v16i8 _1) { return __lsx_vneg_b(_1); } // CHECK-LABEL: @vneg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vneg.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vneg.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vneg_h(v8i16 _1) { return __lsx_vneg_h(_1); } // CHECK-LABEL: @vneg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vneg.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vneg.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vneg_w(v4i32 _1) { return __lsx_vneg_w(_1); } // CHECK-LABEL: @vneg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vneg.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vneg.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vneg_d(v2i64 _1) { return __lsx_vneg_d(_1); } // CHECK-LABEL: @vmuh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmuh_b(v16i8 _1, v16i8 _2) { return __lsx_vmuh_b(_1, _2); } // CHECK-LABEL: @vmuh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmuh_h(v8i16 _1, v8i16 _2) { return __lsx_vmuh_h(_1, _2); } // CHECK-LABEL: @vmuh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmuh_w(v4i32 _1, v4i32 _2) { return __lsx_vmuh_w(_1, _2); } // CHECK-LABEL: @vmuh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmuh_d(v2i64 _1, v2i64 _2) { return __lsx_vmuh_d(_1, _2); } // CHECK-LABEL: @vmuh_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmuh_bu(v16u8 _1, v16u8 _2) { return __lsx_vmuh_bu(_1, _2); } // CHECK-LABEL: @vmuh_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmuh_hu(v8u16 _1, v8u16 _2) { return __lsx_vmuh_hu(_1, _2); } // CHECK-LABEL: @vmuh_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmuh_wu(v4u32 _1, v4u32 _2) { return __lsx_vmuh_wu(_1, _2); } // CHECK-LABEL: @vmuh_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmuh_du(v2u64 _1, v2u64 _2) { return __lsx_vmuh_du(_1, _2); } // CHECK-LABEL: @vsllwil_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsllwil_h_b(v16i8 _1) { return __lsx_vsllwil_h_b(_1, 1); } // CHECK-LABEL: @vsllwil_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsllwil_w_h(v8i16 _1) { return __lsx_vsllwil_w_h(_1, 1); } // CHECK-LABEL: @vsllwil_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsllwil_d_w(v4i32 _1) { return __lsx_vsllwil_d_w(_1, 1); } // CHECK-LABEL: @vsllwil_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vsllwil_hu_bu(v16u8 _1) { return __lsx_vsllwil_hu_bu(_1, 1); } // CHECK-LABEL: @vsllwil_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vsllwil_wu_hu(v8u16 _1) { return __lsx_vsllwil_wu_hu(_1, 1); } // CHECK-LABEL: @vsllwil_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vsllwil_du_wu(v4u32 _1) { return __lsx_vsllwil_du_wu(_1, 1); } // CHECK-LABEL: @vsran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsran.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsran.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsran_b_h(v8i16 _1, v8i16 _2) { return __lsx_vsran_b_h(_1, _2); } // CHECK-LABEL: @vsran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsran.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsran.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsran_h_w(v4i32 _1, v4i32 _2) { return __lsx_vsran_h_w(_1, _2); } // CHECK-LABEL: @vsran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsran.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsran.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsran_w_d(v2i64 _1, v2i64 _2) { return __lsx_vsran_w_d(_1, _2); } // CHECK-LABEL: @vssran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssran_b_h(v8i16 _1, v8i16 _2) { return __lsx_vssran_b_h(_1, _2); } // CHECK-LABEL: @vssran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssran_h_w(v4i32 _1, v4i32 _2) { return __lsx_vssran_h_w(_1, _2); } // CHECK-LABEL: @vssran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssran_w_d(v2i64 _1, v2i64 _2) { return __lsx_vssran_w_d(_1, _2); } // CHECK-LABEL: @vssran_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssran_bu_h(v8u16 _1, v8u16 _2) { return __lsx_vssran_bu_h(_1, _2); } // CHECK-LABEL: @vssran_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssran_hu_w(v4u32 _1, v4u32 _2) { return __lsx_vssran_hu_w(_1, _2); } // CHECK-LABEL: @vssran_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssran_wu_d(v2u64 _1, v2u64 _2) { return __lsx_vssran_wu_d(_1, _2); } // CHECK-LABEL: @vsrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrarn_b_h(v8i16 _1, v8i16 _2) { return __lsx_vsrarn_b_h(_1, _2); } // CHECK-LABEL: @vsrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrarn_h_w(v4i32 _1, v4i32 _2) { return __lsx_vsrarn_h_w(_1, _2); } // CHECK-LABEL: @vsrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrarn_w_d(v2i64 _1, v2i64 _2) { return __lsx_vsrarn_w_d(_1, _2); } // CHECK-LABEL: @vssrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrarn_b_h(v8i16 _1, v8i16 _2) { return __lsx_vssrarn_b_h(_1, _2); } // CHECK-LABEL: @vssrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrarn_h_w(v4i32 _1, v4i32 _2) { return __lsx_vssrarn_h_w(_1, _2); } // CHECK-LABEL: @vssrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrarn_w_d(v2i64 _1, v2i64 _2) { return __lsx_vssrarn_w_d(_1, _2); } // CHECK-LABEL: @vssrarn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrarn_bu_h(v8u16 _1, v8u16 _2) { return __lsx_vssrarn_bu_h(_1, _2); } // CHECK-LABEL: @vssrarn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrarn_hu_w(v4u32 _1, v4u32 _2) { return __lsx_vssrarn_hu_w(_1, _2); } // CHECK-LABEL: @vssrarn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrarn_wu_d(v2u64 _1, v2u64 _2) { return __lsx_vssrarn_wu_d(_1, _2); } // CHECK-LABEL: @vsrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrln.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrln.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrln_b_h(v8i16 _1, v8i16 _2) { return __lsx_vsrln_b_h(_1, _2); } // CHECK-LABEL: @vsrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrln.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrln.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrln_h_w(v4i32 _1, v4i32 _2) { return __lsx_vsrln_h_w(_1, _2); } // CHECK-LABEL: @vsrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrln.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrln.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrln_w_d(v2i64 _1, v2i64 _2) { return __lsx_vsrln_w_d(_1, _2); } // CHECK-LABEL: @vssrln_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrln_bu_h(v8u16 _1, v8u16 _2) { return __lsx_vssrln_bu_h(_1, _2); } // CHECK-LABEL: @vssrln_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrln_hu_w(v4u32 _1, v4u32 _2) { return __lsx_vssrln_hu_w(_1, _2); } // CHECK-LABEL: @vssrln_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrln_wu_d(v2u64 _1, v2u64 _2) { return __lsx_vssrln_wu_d(_1, _2); } // CHECK-LABEL: @vsrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlrn_b_h(v8i16 _1, v8i16 _2) { return __lsx_vsrlrn_b_h(_1, _2); } // CHECK-LABEL: @vsrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlrn_h_w(v4i32 _1, v4i32 _2) { return __lsx_vsrlrn_h_w(_1, _2); } // CHECK-LABEL: @vsrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlrn_w_d(v2i64 _1, v2i64 _2) { return __lsx_vsrlrn_w_d(_1, _2); } // CHECK-LABEL: @vssrlrn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrlrn_bu_h(v8u16 _1, v8u16 _2) { return __lsx_vssrlrn_bu_h(_1, _2); } // CHECK-LABEL: @vssrlrn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrlrn_hu_w(v4u32 _1, v4u32 _2) { return __lsx_vssrlrn_hu_w(_1, _2); } // CHECK-LABEL: @vssrlrn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrlrn_wu_d(v2u64 _1, v2u64 _2) { return __lsx_vssrlrn_wu_d(_1, _2); } // CHECK-LABEL: @vfrstpi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vfrstpi_b(v16i8 _1, v16i8 _2) { return __lsx_vfrstpi_b(_1, _2, 1); } // CHECK-LABEL: @vfrstpi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vfrstpi_h(v8i16 _1, v8i16 _2) { return __lsx_vfrstpi_h(_1, _2, 1); } // CHECK-LABEL: @vfrstp_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstp.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstp.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vfrstp_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __lsx_vfrstp_b(_1, _2, _3); } // CHECK-LABEL: @vfrstp_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstp.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstp.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vfrstp_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __lsx_vfrstp_h(_1, _2, _3); } // CHECK-LABEL: @vshuf4i_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vshuf4i_d(v2i64 _1, v2i64 _2) { return __lsx_vshuf4i_d(_1, _2, 1); } // CHECK-LABEL: @vbsrl_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vbsrl_v(v16i8 _1) { return __lsx_vbsrl_v(_1, 1); } // CHECK-LABEL: @vbsll_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vbsll_v(v16i8 _1) { return __lsx_vbsll_v(_1, 1); } // CHECK-LABEL: @vextrins_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vextrins_b(v16i8 _1, v16i8 _2) { return __lsx_vextrins_b(_1, _2, 1); } // CHECK-LABEL: @vextrins_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vextrins_h(v8i16 _1, v8i16 _2) { return __lsx_vextrins_h(_1, _2, 1); } // CHECK-LABEL: @vextrins_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vextrins_w(v4i32 _1, v4i32 _2) { return __lsx_vextrins_w(_1, _2, 1); } // CHECK-LABEL: @vextrins_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vextrins_d(v2i64 _1, v2i64 _2) { return __lsx_vextrins_d(_1, _2, 1); } // CHECK-LABEL: @vmskltz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskltz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskltz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmskltz_b(v16i8 _1) { return __lsx_vmskltz_b(_1); } // CHECK-LABEL: @vmskltz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmskltz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmskltz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vmskltz_h(v8i16 _1) { return __lsx_vmskltz_h(_1); } // CHECK-LABEL: @vmskltz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmskltz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmskltz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vmskltz_w(v4i32 _1) { return __lsx_vmskltz_w(_1); } // CHECK-LABEL: @vmskltz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmskltz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmskltz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vmskltz_d(v2i64 _1) { return __lsx_vmskltz_d(_1); } // CHECK-LABEL: @vsigncov_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsigncov.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsigncov.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsigncov_b(v16i8 _1, v16i8 _2) { return __lsx_vsigncov_b(_1, _2); } // CHECK-LABEL: @vsigncov_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsigncov.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsigncov.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsigncov_h(v8i16 _1, v8i16 _2) { return __lsx_vsigncov_h(_1, _2); } // CHECK-LABEL: @vsigncov_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsigncov.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsigncov.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsigncov_w(v4i32 _1, v4i32 _2) { return __lsx_vsigncov_w(_1, _2); } // CHECK-LABEL: @vsigncov_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsigncov.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsigncov.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsigncov_d(v2i64 _1, v2i64 _2) { return __lsx_vsigncov_d(_1, _2); } // CHECK-LABEL: @vfmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmadd.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmadd.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfmadd_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __lsx_vfmadd_s(_1, _2, _3); } // CHECK-LABEL: @vfmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmadd.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmadd.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfmadd_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __lsx_vfmadd_d(_1, _2, _3); } // CHECK-LABEL: @vfmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmsub.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmsub.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfmsub_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __lsx_vfmsub_s(_1, _2, _3); } // CHECK-LABEL: @vfmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmsub.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmsub.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfmsub_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __lsx_vfmsub_d(_1, _2, _3); } // CHECK-LABEL: @vfnmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmadd.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmadd.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfnmadd_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __lsx_vfnmadd_s(_1, _2, _3); } // CHECK-LABEL: @vfnmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmadd.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmadd.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfnmadd_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __lsx_vfnmadd_d(_1, _2, _3); } // CHECK-LABEL: @vfnmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmsub.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmsub.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfnmsub_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __lsx_vfnmsub_s(_1, _2, _3); } // CHECK-LABEL: @vfnmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmsub.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmsub.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfnmsub_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __lsx_vfnmsub_d(_1, _2, _3); } // CHECK-LABEL: @vftintrne_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrne_w_s(v4f32 _1) { return __lsx_vftintrne_w_s(_1); } // CHECK-LABEL: @vftintrne_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrne.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrne.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrne_l_d(v2f64 _1) { return __lsx_vftintrne_l_d(_1); } // CHECK-LABEL: @vftintrp_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrp_w_s(v4f32 _1) { return __lsx_vftintrp_w_s(_1); } // CHECK-LABEL: @vftintrp_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrp.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrp.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrp_l_d(v2f64 _1) { return __lsx_vftintrp_l_d(_1); } // CHECK-LABEL: @vftintrm_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrm_w_s(v4f32 _1) { return __lsx_vftintrm_w_s(_1); } // CHECK-LABEL: @vftintrm_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrm.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrm.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrm_l_d(v2f64 _1) { return __lsx_vftintrm_l_d(_1); } // CHECK-LABEL: @vftint_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftint_w_d(v2f64 _1, v2f64 _2) { return __lsx_vftint_w_d(_1, _2); } // CHECK-LABEL: @vffint_s_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.l(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.l(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vffint_s_l(v2i64 _1, v2i64 _2) { return __lsx_vffint_s_l(_1, _2); } // CHECK-LABEL: @vftintrz_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrz_w_d(v2f64 _1, v2f64 _2) { return __lsx_vftintrz_w_d(_1, _2); } // CHECK-LABEL: @vftintrp_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrp_w_d(v2f64 _1, v2f64 _2) { return __lsx_vftintrp_w_d(_1, _2); } // CHECK-LABEL: @vftintrm_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrm_w_d(v2f64 _1, v2f64 _2) { return __lsx_vftintrm_w_d(_1, _2); } // CHECK-LABEL: @vftintrne_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrne_w_d(v2f64 _1, v2f64 _2) { return __lsx_vftintrne_w_d(_1, _2); } // CHECK-LABEL: @vftintl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintl.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintl.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintl_l_s(v4f32 _1) { return __lsx_vftintl_l_s(_1); } // CHECK-LABEL: @vftinth_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftinth.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftinth.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftinth_l_s(v4f32 _1) { return __lsx_vftinth_l_s(_1); } // CHECK-LABEL: @vffinth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffinth.d.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffinth.d.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffinth_d_w(v4i32 _1) { return __lsx_vffinth_d_w(_1); } // CHECK-LABEL: @vffintl_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffintl.d.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffintl.d.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffintl_d_w(v4i32 _1) { return __lsx_vffintl_d_w(_1); } // CHECK-LABEL: @vftintrzl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzl.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzl.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrzl_l_s(v4f32 _1) { return __lsx_vftintrzl_l_s(_1); } // CHECK-LABEL: @vftintrzh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzh.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzh.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrzh_l_s(v4f32 _1) { return __lsx_vftintrzh_l_s(_1); } // CHECK-LABEL: @vftintrpl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrpl.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrpl.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrpl_l_s(v4f32 _1) { return __lsx_vftintrpl_l_s(_1); } // CHECK-LABEL: @vftintrph_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrph.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrph.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrph_l_s(v4f32 _1) { return __lsx_vftintrph_l_s(_1); } // CHECK-LABEL: @vftintrml_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrml.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrml.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrml_l_s(v4f32 _1) { return __lsx_vftintrml_l_s(_1); } // CHECK-LABEL: @vftintrmh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrmh.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrmh.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrmh_l_s(v4f32 _1) { return __lsx_vftintrmh_l_s(_1); } // CHECK-LABEL: @vftintrnel_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrnel.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrnel.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrnel_l_s(v4f32 _1) { return __lsx_vftintrnel_l_s(_1); } // CHECK-LABEL: @vftintrneh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrneh.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrneh.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrneh_l_s(v4f32 _1) { return __lsx_vftintrneh_l_s(_1); } // CHECK-LABEL: @vfrintrne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrne.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrne.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrne_s(v4f32 _1) { return __lsx_vfrintrne_s(_1); } // CHECK-LABEL: @vfrintrne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrne.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrne.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrne_d(v2f64 _1) { return __lsx_vfrintrne_d(_1); } // CHECK-LABEL: @vfrintrz_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrz.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrz.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrz_s(v4f32 _1) { return __lsx_vfrintrz_s(_1); } // CHECK-LABEL: @vfrintrz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrz.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrz.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrz_d(v2f64 _1) { return __lsx_vfrintrz_d(_1); } // CHECK-LABEL: @vfrintrp_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrp.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrp.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrp_s(v4f32 _1) { return __lsx_vfrintrp_s(_1); } // CHECK-LABEL: @vfrintrp_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrp.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrp.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrp_d(v2f64 _1) { return __lsx_vfrintrp_d(_1); } // CHECK-LABEL: @vfrintrm_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrm.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrm.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrm_s(v4f32 _1) { return __lsx_vfrintrm_s(_1); } // CHECK-LABEL: @vfrintrm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrm.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrm.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrm_d(v2f64 _1) { return __lsx_vfrintrm_d(_1); } // CHECK-LABEL: @vstelm_b( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> [[TMP0]], ptr [[_2:%.*]], i32 1, i32 1) // CHECK-NEXT: ret void // void vstelm_b(v16i8 _1, void *_2) { return __lsx_vstelm_b(_1, _2, 1, 1); } // CHECK-LABEL: @vstelm_h( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> [[_1:%.*]], ptr [[_2:%.*]], i32 2, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> [[TMP0]], ptr [[_2:%.*]], i32 2, i32 1) // CHECK-NEXT: ret void // void vstelm_h(v8i16 _1, void *_2) { return __lsx_vstelm_h(_1, _2, 2, 1); } // CHECK-LABEL: @vstelm_w( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> [[_1:%.*]], ptr [[_2:%.*]], i32 4, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> [[TMP0]], ptr [[_2:%.*]], i32 4, i32 1) // CHECK-NEXT: ret void // void vstelm_w(v4i32 _1, void *_2) { return __lsx_vstelm_w(_1, _2, 4, 1); } // CHECK-LABEL: @vstelm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> [[_1:%.*]], ptr [[_2:%.*]], i32 8, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> [[TMP0]], ptr [[_2:%.*]], i32 8, i32 1) // CHECK-NEXT: ret void // void vstelm_d(v2i64 _1, void *_2) { return __lsx_vstelm_d(_1, _2, 8, 1); } // CHECK-LABEL: @vaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_d_w(v4i32 _1, v4i32 _2) { return __lsx_vaddwev_d_w(_1, _2); } // CHECK-LABEL: @vaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwev_w_h(v8i16 _1, v8i16 _2) { return __lsx_vaddwev_w_h(_1, _2); } // CHECK-LABEL: @vaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwev_h_b(v16i8 _1, v16i8 _2) { return __lsx_vaddwev_h_b(_1, _2); } // CHECK-LABEL: @vaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_d_w(v4i32 _1, v4i32 _2) { return __lsx_vaddwod_d_w(_1, _2); } // CHECK-LABEL: @vaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwod_w_h(v8i16 _1, v8i16 _2) { return __lsx_vaddwod_w_h(_1, _2); } // CHECK-LABEL: @vaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwod_h_b(v16i8 _1, v16i8 _2) { return __lsx_vaddwod_h_b(_1, _2); } // CHECK-LABEL: @vaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_d_wu(v4u32 _1, v4u32 _2) { return __lsx_vaddwev_d_wu(_1, _2); } // CHECK-LABEL: @vaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwev_w_hu(v8u16 _1, v8u16 _2) { return __lsx_vaddwev_w_hu(_1, _2); } // CHECK-LABEL: @vaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwev_h_bu(v16u8 _1, v16u8 _2) { return __lsx_vaddwev_h_bu(_1, _2); } // CHECK-LABEL: @vaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_d_wu(v4u32 _1, v4u32 _2) { return __lsx_vaddwod_d_wu(_1, _2); } // CHECK-LABEL: @vaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwod_w_hu(v8u16 _1, v8u16 _2) { return __lsx_vaddwod_w_hu(_1, _2); } // CHECK-LABEL: @vaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwod_h_bu(v16u8 _1, v16u8 _2) { return __lsx_vaddwod_h_bu(_1, _2); } // CHECK-LABEL: @vaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_d_wu_w(v4u32 _1, v4i32 _2) { return __lsx_vaddwev_d_wu_w(_1, _2); } // CHECK-LABEL: @vaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwev_w_hu_h(v8u16 _1, v8i16 _2) { return __lsx_vaddwev_w_hu_h(_1, _2); } // CHECK-LABEL: @vaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwev_h_bu_b(v16u8 _1, v16i8 _2) { return __lsx_vaddwev_h_bu_b(_1, _2); } // CHECK-LABEL: @vaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_d_wu_w(v4u32 _1, v4i32 _2) { return __lsx_vaddwod_d_wu_w(_1, _2); } // CHECK-LABEL: @vaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwod_w_hu_h(v8u16 _1, v8i16 _2) { return __lsx_vaddwod_w_hu_h(_1, _2); } // CHECK-LABEL: @vaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwod_h_bu_b(v16u8 _1, v16i8 _2) { return __lsx_vaddwod_h_bu_b(_1, _2); } // CHECK-LABEL: @vsubwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_d_w(v4i32 _1, v4i32 _2) { return __lsx_vsubwev_d_w(_1, _2); } // CHECK-LABEL: @vsubwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwev_w_h(v8i16 _1, v8i16 _2) { return __lsx_vsubwev_w_h(_1, _2); } // CHECK-LABEL: @vsubwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwev_h_b(v16i8 _1, v16i8 _2) { return __lsx_vsubwev_h_b(_1, _2); } // CHECK-LABEL: @vsubwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_d_w(v4i32 _1, v4i32 _2) { return __lsx_vsubwod_d_w(_1, _2); } // CHECK-LABEL: @vsubwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwod_w_h(v8i16 _1, v8i16 _2) { return __lsx_vsubwod_w_h(_1, _2); } // CHECK-LABEL: @vsubwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwod_h_b(v16i8 _1, v16i8 _2) { return __lsx_vsubwod_h_b(_1, _2); } // CHECK-LABEL: @vsubwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_d_wu(v4u32 _1, v4u32 _2) { return __lsx_vsubwev_d_wu(_1, _2); } // CHECK-LABEL: @vsubwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwev_w_hu(v8u16 _1, v8u16 _2) { return __lsx_vsubwev_w_hu(_1, _2); } // CHECK-LABEL: @vsubwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwev_h_bu(v16u8 _1, v16u8 _2) { return __lsx_vsubwev_h_bu(_1, _2); } // CHECK-LABEL: @vsubwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_d_wu(v4u32 _1, v4u32 _2) { return __lsx_vsubwod_d_wu(_1, _2); } // CHECK-LABEL: @vsubwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwod_w_hu(v8u16 _1, v8u16 _2) { return __lsx_vsubwod_w_hu(_1, _2); } // CHECK-LABEL: @vsubwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwod_h_bu(v16u8 _1, v16u8 _2) { return __lsx_vsubwod_h_bu(_1, _2); } // CHECK-LABEL: @vaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_q_d(v2i64 _1, v2i64 _2) { return __lsx_vaddwev_q_d(_1, _2); } // CHECK-LABEL: @vaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_q_d(v2i64 _1, v2i64 _2) { return __lsx_vaddwod_q_d(_1, _2); } // CHECK-LABEL: @vaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_q_du(v2u64 _1, v2u64 _2) { return __lsx_vaddwev_q_du(_1, _2); } // CHECK-LABEL: @vaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_q_du(v2u64 _1, v2u64 _2) { return __lsx_vaddwod_q_du(_1, _2); } // CHECK-LABEL: @vsubwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_q_d(v2i64 _1, v2i64 _2) { return __lsx_vsubwev_q_d(_1, _2); } // CHECK-LABEL: @vsubwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_q_d(v2i64 _1, v2i64 _2) { return __lsx_vsubwod_q_d(_1, _2); } // CHECK-LABEL: @vsubwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_q_du(v2u64 _1, v2u64 _2) { return __lsx_vsubwev_q_du(_1, _2); } // CHECK-LABEL: @vsubwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_q_du(v2u64 _1, v2u64 _2) { return __lsx_vsubwod_q_du(_1, _2); } // CHECK-LABEL: @vaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_q_du_d(v2u64 _1, v2i64 _2) { return __lsx_vaddwev_q_du_d(_1, _2); } // CHECK-LABEL: @vaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_q_du_d(v2u64 _1, v2i64 _2) { return __lsx_vaddwod_q_du_d(_1, _2); } // CHECK-LABEL: @vmulwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_d_w(v4i32 _1, v4i32 _2) { return __lsx_vmulwev_d_w(_1, _2); } // CHECK-LABEL: @vmulwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwev_w_h(v8i16 _1, v8i16 _2) { return __lsx_vmulwev_w_h(_1, _2); } // CHECK-LABEL: @vmulwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwev_h_b(v16i8 _1, v16i8 _2) { return __lsx_vmulwev_h_b(_1, _2); } // CHECK-LABEL: @vmulwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_d_w(v4i32 _1, v4i32 _2) { return __lsx_vmulwod_d_w(_1, _2); } // CHECK-LABEL: @vmulwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwod_w_h(v8i16 _1, v8i16 _2) { return __lsx_vmulwod_w_h(_1, _2); } // CHECK-LABEL: @vmulwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwod_h_b(v16i8 _1, v16i8 _2) { return __lsx_vmulwod_h_b(_1, _2); } // CHECK-LABEL: @vmulwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_d_wu(v4u32 _1, v4u32 _2) { return __lsx_vmulwev_d_wu(_1, _2); } // CHECK-LABEL: @vmulwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwev_w_hu(v8u16 _1, v8u16 _2) { return __lsx_vmulwev_w_hu(_1, _2); } // CHECK-LABEL: @vmulwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwev_h_bu(v16u8 _1, v16u8 _2) { return __lsx_vmulwev_h_bu(_1, _2); } // CHECK-LABEL: @vmulwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_d_wu(v4u32 _1, v4u32 _2) { return __lsx_vmulwod_d_wu(_1, _2); } // CHECK-LABEL: @vmulwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwod_w_hu(v8u16 _1, v8u16 _2) { return __lsx_vmulwod_w_hu(_1, _2); } // CHECK-LABEL: @vmulwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwod_h_bu(v16u8 _1, v16u8 _2) { return __lsx_vmulwod_h_bu(_1, _2); } // CHECK-LABEL: @vmulwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_d_wu_w(v4u32 _1, v4i32 _2) { return __lsx_vmulwev_d_wu_w(_1, _2); } // CHECK-LABEL: @vmulwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwev_w_hu_h(v8u16 _1, v8i16 _2) { return __lsx_vmulwev_w_hu_h(_1, _2); } // CHECK-LABEL: @vmulwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwev_h_bu_b(v16u8 _1, v16i8 _2) { return __lsx_vmulwev_h_bu_b(_1, _2); } // CHECK-LABEL: @vmulwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_d_wu_w(v4u32 _1, v4i32 _2) { return __lsx_vmulwod_d_wu_w(_1, _2); } // CHECK-LABEL: @vmulwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwod_w_hu_h(v8u16 _1, v8i16 _2) { return __lsx_vmulwod_w_hu_h(_1, _2); } // CHECK-LABEL: @vmulwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwod_h_bu_b(v16u8 _1, v16i8 _2) { return __lsx_vmulwod_h_bu_b(_1, _2); } // CHECK-LABEL: @vmulwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_q_d(v2i64 _1, v2i64 _2) { return __lsx_vmulwev_q_d(_1, _2); } // CHECK-LABEL: @vmulwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_q_d(v2i64 _1, v2i64 _2) { return __lsx_vmulwod_q_d(_1, _2); } // CHECK-LABEL: @vmulwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_q_du(v2u64 _1, v2u64 _2) { return __lsx_vmulwev_q_du(_1, _2); } // CHECK-LABEL: @vmulwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_q_du(v2u64 _1, v2u64 _2) { return __lsx_vmulwod_q_du(_1, _2); } // CHECK-LABEL: @vmulwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_q_du_d(v2u64 _1, v2i64 _2) { return __lsx_vmulwev_q_du_d(_1, _2); } // CHECK-LABEL: @vmulwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_q_du_d(v2u64 _1, v2i64 _2) { return __lsx_vmulwod_q_du_d(_1, _2); } // CHECK-LABEL: @vhaddw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhaddw_q_d(v2i64 _1, v2i64 _2) { return __lsx_vhaddw_q_d(_1, _2); } // CHECK-LABEL: @vhaddw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.qu.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.qu.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vhaddw_qu_du(v2u64 _1, v2u64 _2) { return __lsx_vhaddw_qu_du(_1, _2); } // CHECK-LABEL: @vhsubw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhsubw_q_d(v2i64 _1, v2i64 _2) { return __lsx_vhsubw_q_d(_1, _2); } // CHECK-LABEL: @vhsubw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.qu.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.qu.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vhsubw_qu_du(v2u64 _1, v2u64 _2) { return __lsx_vhsubw_qu_du(_1, _2); } // CHECK-LABEL: @vmaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_d_w(v2i64 _1, v4i32 _2, v4i32 _3) { return __lsx_vmaddwev_d_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwev_w_h(v4i32 _1, v8i16 _2, v8i16 _3) { return __lsx_vmaddwev_w_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwev_h_b(v8i16 _1, v16i8 _2, v16i8 _3) { return __lsx_vmaddwev_h_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwev_d_wu(v2u64 _1, v4u32 _2, v4u32 _3) { return __lsx_vmaddwev_d_wu(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4u32 vmaddwev_w_hu(v4u32 _1, v8u16 _2, v8u16 _3) { return __lsx_vmaddwev_w_hu(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8u16 vmaddwev_h_bu(v8u16 _1, v16u8 _2, v16u8 _3) { return __lsx_vmaddwev_h_bu(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_d_w(v2i64 _1, v4i32 _2, v4i32 _3) { return __lsx_vmaddwod_d_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwod_w_h(v4i32 _1, v8i16 _2, v8i16 _3) { return __lsx_vmaddwod_w_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwod_h_b(v8i16 _1, v16i8 _2, v16i8 _3) { return __lsx_vmaddwod_h_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwod_d_wu(v2u64 _1, v4u32 _2, v4u32 _3) { return __lsx_vmaddwod_d_wu(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4u32 vmaddwod_w_hu(v4u32 _1, v8u16 _2, v8u16 _3) { return __lsx_vmaddwod_w_hu(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8u16 vmaddwod_h_bu(v8u16 _1, v16u8 _2, v16u8 _3) { return __lsx_vmaddwod_h_bu(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_d_wu_w(v2i64 _1, v4u32 _2, v4i32 _3) { return __lsx_vmaddwev_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwev_w_hu_h(v4i32 _1, v8u16 _2, v8i16 _3) { return __lsx_vmaddwev_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwev_h_bu_b(v8i16 _1, v16u8 _2, v16i8 _3) { return __lsx_vmaddwev_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_d_wu_w(v2i64 _1, v4u32 _2, v4i32 _3) { return __lsx_vmaddwod_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwod_w_hu_h(v4i32 _1, v8u16 _2, v8i16 _3) { return __lsx_vmaddwod_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwod_h_bu_b(v8i16 _1, v16u8 _2, v16i8 _3) { return __lsx_vmaddwod_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_q_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __lsx_vmaddwev_q_d(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_q_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __lsx_vmaddwod_q_d(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwev_q_du(v2u64 _1, v2u64 _2, v2u64 _3) { return __lsx_vmaddwev_q_du(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwod_q_du(v2u64 _1, v2u64 _2, v2u64 _3) { return __lsx_vmaddwod_q_du(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_q_du_d(v2i64 _1, v2u64 _2, v2i64 _3) { return __lsx_vmaddwev_q_du_d(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_q_du_d(v2i64 _1, v2u64 _2, v2i64 _3) { return __lsx_vmaddwod_q_du_d(_1, _2, _3); } // CHECK-LABEL: @vrotr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vrotr_b(v16i8 _1, v16i8 _2) { return __lsx_vrotr_b(_1, _2); } // CHECK-LABEL: @vrotr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vrotr_h(v8i16 _1, v8i16 _2) { return __lsx_vrotr_h(_1, _2); } // CHECK-LABEL: @vrotr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vrotr_w(v4i32 _1, v4i32 _2) { return __lsx_vrotr_w(_1, _2); } // CHECK-LABEL: @vrotr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vrotr_d(v2i64 _1, v2i64 _2) { return __lsx_vrotr_d(_1, _2); } // CHECK-LABEL: @vadd_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vadd_q(v2i64 _1, v2i64 _2) { return __lsx_vadd_q(_1, _2); } // CHECK-LABEL: @vsub_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsub_q(v2i64 _1, v2i64 _2) { return __lsx_vsub_q(_1, _2); } // CHECK-LABEL: @vldrepl_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vldrepl.b(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vldrepl_b(void *_1) { return __lsx_vldrepl_b(_1, 1); } // CHECK-LABEL: @vldrepl_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vldrepl.h(ptr [[_1:%.*]], i32 2) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v8i16 vldrepl_h(void *_1) { return __lsx_vldrepl_h(_1, 2); } // CHECK-LABEL: @vldrepl_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(ptr [[_1:%.*]], i32 4) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v4i32 vldrepl_w(void *_1) { return __lsx_vldrepl_w(_1, 4); } // CHECK-LABEL: @vldrepl_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vldrepl.d(ptr [[_1:%.*]], i32 8) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vldrepl_d(void *_1) { return __lsx_vldrepl_d(_1, 8); } // CHECK-LABEL: @vmskgez_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskgez.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskgez.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmskgez_b(v16i8 _1) { return __lsx_vmskgez_b(_1); } // CHECK-LABEL: @vmsknz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsknz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsknz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmsknz_b(v16i8 _1) { return __lsx_vmsknz_b(_1); } // CHECK-LABEL: @vexth_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.h.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.h.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vexth_h_b(v16i8 _1) { return __lsx_vexth_h_b(_1); } // CHECK-LABEL: @vexth_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.w.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.w.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vexth_w_h(v8i16 _1) { return __lsx_vexth_w_h(_1); } // CHECK-LABEL: @vexth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.d.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.d.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vexth_d_w(v4i32 _1) { return __lsx_vexth_d_w(_1); } // CHECK-LABEL: @vexth_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.q.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.q.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vexth_q_d(v2i64 _1) { return __lsx_vexth_q_d(_1); } // CHECK-LABEL: @vexth_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.hu.bu(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.hu.bu(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vexth_hu_bu(v16u8 _1) { return __lsx_vexth_hu_bu(_1); } // CHECK-LABEL: @vexth_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.wu.hu(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.wu.hu(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vexth_wu_hu(v8u16 _1) { return __lsx_vexth_wu_hu(_1); } // CHECK-LABEL: @vexth_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.du.wu(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.du.wu(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vexth_du_wu(v4u32 _1) { return __lsx_vexth_du_wu(_1); } // CHECK-LABEL: @vexth_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.qu.du(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.qu.du(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vexth_qu_du(v2u64 _1) { return __lsx_vexth_qu_du(_1); } // CHECK-LABEL: @vrotri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vrotri_b(v16i8 _1) { return __lsx_vrotri_b(_1, 1); } // CHECK-LABEL: @vrotri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vrotri_h(v8i16 _1) { return __lsx_vrotri_h(_1, 1); } // CHECK-LABEL: @vrotri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vrotri_w(v4i32 _1) { return __lsx_vrotri_w(_1, 1); } // CHECK-LABEL: @vrotri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vrotri_d(v2i64 _1) { return __lsx_vrotri_d(_1, 1); } // CHECK-LABEL: @vextl_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.q.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.q.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vextl_q_d(v2i64 _1) { return __lsx_vextl_q_d(_1); } // CHECK-LABEL: @vsrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlni_b_h(v16i8 _1, v16i8 _2) { return __lsx_vsrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlni_h_w(v8i16 _1, v8i16 _2) { return __lsx_vsrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlni_w_d(v4i32 _1, v4i32 _2) { return __lsx_vsrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrlni_d_q(v2i64 _1, v2i64 _2) { return __lsx_vsrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlrni_b_h(v16i8 _1, v16i8 _2) { return __lsx_vsrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlrni_h_w(v8i16 _1, v8i16 _2) { return __lsx_vsrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlrni_w_d(v4i32 _1, v4i32 _2) { return __lsx_vsrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrlrni_d_q(v2i64 _1, v2i64 _2) { return __lsx_vsrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrlni_b_h(v16i8 _1, v16i8 _2) { return __lsx_vssrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrlni_h_w(v8i16 _1, v8i16 _2) { return __lsx_vssrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrlni_w_d(v4i32 _1, v4i32 _2) { return __lsx_vssrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrlni_d_q(v2i64 _1, v2i64 _2) { return __lsx_vssrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrlni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrlni_bu_h(v16u8 _1, v16i8 _2) { return __lsx_vssrlni_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrlni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrlni_hu_w(v8u16 _1, v8i16 _2) { return __lsx_vssrlni_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrlni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrlni_wu_d(v4u32 _1, v4i32 _2) { return __lsx_vssrlni_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrlni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrlni_du_q(v2u64 _1, v2i64 _2) { return __lsx_vssrlni_du_q(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrlrni_b_h(v16i8 _1, v16i8 _2) { return __lsx_vssrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrlrni_h_w(v8i16 _1, v8i16 _2) { return __lsx_vssrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrlrni_w_d(v4i32 _1, v4i32 _2) { return __lsx_vssrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrlrni_d_q(v2i64 _1, v2i64 _2) { return __lsx_vssrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrlrni_bu_h(v16u8 _1, v16i8 _2) { return __lsx_vssrlrni_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrlrni_hu_w(v8u16 _1, v8i16 _2) { return __lsx_vssrlrni_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrlrni_wu_d(v4u32 _1, v4i32 _2) { return __lsx_vssrlrni_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrlrni_du_q(v2u64 _1, v2i64 _2) { return __lsx_vssrlrni_du_q(_1, _2, 1); } // CHECK-LABEL: @vsrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrani_b_h(v16i8 _1, v16i8 _2) { return __lsx_vsrani_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrani_h_w(v8i16 _1, v8i16 _2) { return __lsx_vsrani_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrani_w_d(v4i32 _1, v4i32 _2) { return __lsx_vsrani_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrani_d_q(v2i64 _1, v2i64 _2) { return __lsx_vsrani_d_q(_1, _2, 1); } // CHECK-LABEL: @vsrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrarni_b_h(v16i8 _1, v16i8 _2) { return __lsx_vsrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrarni_h_w(v8i16 _1, v8i16 _2) { return __lsx_vsrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrarni_w_d(v4i32 _1, v4i32 _2) { return __lsx_vsrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrarni_d_q(v2i64 _1, v2i64 _2) { return __lsx_vsrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrani_b_h(v16i8 _1, v16i8 _2) { return __lsx_vssrani_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrani_h_w(v8i16 _1, v8i16 _2) { return __lsx_vssrani_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrani_w_d(v4i32 _1, v4i32 _2) { return __lsx_vssrani_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrani_d_q(v2i64 _1, v2i64 _2) { return __lsx_vssrani_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrani_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrani_bu_h(v16u8 _1, v16i8 _2) { return __lsx_vssrani_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrani_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrani_hu_w(v8u16 _1, v8i16 _2) { return __lsx_vssrani_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrani_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrani_wu_d(v4u32 _1, v4i32 _2) { return __lsx_vssrani_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrani_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrani_du_q(v2u64 _1, v2i64 _2) { return __lsx_vssrani_du_q(_1, _2, 1); } // CHECK-LABEL: @vssrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrarni_b_h(v16i8 _1, v16i8 _2) { return __lsx_vssrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrarni_h_w(v8i16 _1, v8i16 _2) { return __lsx_vssrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrarni_w_d(v4i32 _1, v4i32 _2) { return __lsx_vssrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrarni_d_q(v2i64 _1, v2i64 _2) { return __lsx_vssrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrarni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrarni_bu_h(v16u8 _1, v16i8 _2) { return __lsx_vssrarni_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrarni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrarni_hu_w(v8u16 _1, v8i16 _2) { return __lsx_vssrarni_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrarni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrarni_wu_d(v4u32 _1, v4i32 _2) { return __lsx_vssrarni_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrarni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrarni_du_q(v2u64 _1, v2i64 _2) { return __lsx_vssrarni_du_q(_1, _2, 1); } // CHECK-LABEL: @vpermi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpermi_w(v4i32 _1, v4i32 _2) { return __lsx_vpermi_w(_1, _2, 1); } // CHECK-LABEL: @vld( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vld(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vld(void *_1) { return __lsx_vld(_1, 1); } // CHECK-LABEL: @vst( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vst(<16 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vst(<16 x i8> [[TMP0]], ptr [[_2:%.*]], i32 1) // CHECK-NEXT: ret void // void vst(v16i8 _1, void *_2) { return __lsx_vst(_1, _2, 1); } // CHECK-LABEL: @vssrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrlrn_b_h(v8i16 _1, v8i16 _2) { return __lsx_vssrlrn_b_h(_1, _2); } // CHECK-LABEL: @vssrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrlrn_h_w(v4i32 _1, v4i32 _2) { return __lsx_vssrlrn_h_w(_1, _2); } // CHECK-LABEL: @vssrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrlrn_w_d(v2i64 _1, v2i64 _2) { return __lsx_vssrlrn_w_d(_1, _2); } // CHECK-LABEL: @vssrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrln_b_h(v8i16 _1, v8i16 _2) { return __lsx_vssrln_b_h(_1, _2); } // CHECK-LABEL: @vssrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrln_h_w(v4i32 _1, v4i32 _2) { return __lsx_vssrln_h_w(_1, _2); } // CHECK-LABEL: @vssrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrln_w_d(v2i64 _1, v2i64 _2) { return __lsx_vssrln_w_d(_1, _2); } // CHECK-LABEL: @vorn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vorn.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vorn.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vorn_v(v16i8 _1, v16i8 _2) { return __lsx_vorn_v(_1, _2); } // CHECK-LABEL: @vldi( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vldi(i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vldi() { return __lsx_vldi(1); } // CHECK-LABEL: @vshuf_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vshuf_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __lsx_vshuf_b(_1, _2, _3); @@ -4086,366 +5844,516 @@ v16i8 vshuf_b(v16i8 _1, v16i8 _2, v16i8 _3) { // CHECK-LABEL: @vldx( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vldx(ptr [[_1:%.*]], i64 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vldx(void *_1) { return __lsx_vldx(_1, 1); } // CHECK-LABEL: @vstx( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstx(<16 x i8> [[_1:%.*]], ptr [[_2:%.*]], i64 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstx(<16 x i8> [[TMP0]], ptr [[_2:%.*]], i64 1) // CHECK-NEXT: ret void // void vstx(v16i8 _1, void *_2) { return __lsx_vstx(_1, _2, 1); } // CHECK-LABEL: @vextl_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.qu.du(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.qu.du(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vextl_qu_du(v2u64 _1) { return __lsx_vextl_qu_du(_1); } // CHECK-LABEL: @bnz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_b(v16u8 _1) { return __lsx_bnz_b(_1); } // CHECK-LABEL: @bnz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_d(v2u64 _1) { return __lsx_bnz_d(_1); } // CHECK-LABEL: @bnz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_h(v8u16 _1) { return __lsx_bnz_h(_1); } // CHECK-LABEL: @bnz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.v(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.v(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_v(v16u8 _1) { return __lsx_bnz_v(_1); } // CHECK-LABEL: @bnz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_w(v4u32 _1) { return __lsx_bnz_w(_1); } // CHECK-LABEL: @bz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_b(v16u8 _1) { return __lsx_bz_b(_1); } // CHECK-LABEL: @bz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_d(v2u64 _1) { return __lsx_bz_d(_1); } // CHECK-LABEL: @bz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_h(v8u16 _1) { return __lsx_bz_h(_1); } // CHECK-LABEL: @bz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.v(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.v(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_v(v16u8 _1) { return __lsx_bz_v(_1); } // CHECK-LABEL: @bz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_w(v4u32 _1) { return __lsx_bz_w(_1); } // CHECK-LABEL: @vfcmp_caf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.caf.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.caf.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_caf_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_caf_d(_1, _2); } // CHECK-LABEL: @vfcmp_caf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.caf.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.caf.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_caf_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_caf_s(_1, _2); } // CHECK-LABEL: @vfcmp_ceq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.ceq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.ceq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_ceq_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_ceq_d(_1, _2); } // CHECK-LABEL: @vfcmp_ceq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.ceq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.ceq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_ceq_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_ceq_s(_1, _2); } // CHECK-LABEL: @vfcmp_cle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cle.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cle.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cle_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cle_d(_1, _2); } // CHECK-LABEL: @vfcmp_cle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cle.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cle.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cle_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cle_s(_1, _2); } // CHECK-LABEL: @vfcmp_clt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.clt.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.clt.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_clt_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_clt_d(_1, _2); } // CHECK-LABEL: @vfcmp_clt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.clt.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.clt.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_clt_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_clt_s(_1, _2); } // CHECK-LABEL: @vfcmp_cne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cne.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cne.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cne_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cne_d(_1, _2); } // CHECK-LABEL: @vfcmp_cne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cne.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cne.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cne_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cne_s(_1, _2); } // CHECK-LABEL: @vfcmp_cor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cor.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cor.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cor_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cor_d(_1, _2); } // CHECK-LABEL: @vfcmp_cor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cor.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cor.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cor_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cor_s(_1, _2); } // CHECK-LABEL: @vfcmp_cueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cueq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cueq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cueq_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cueq_d(_1, _2); } // CHECK-LABEL: @vfcmp_cueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cueq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cueq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cueq_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cueq_s(_1, _2); } // CHECK-LABEL: @vfcmp_cule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cule.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cule.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cule_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cule_d(_1, _2); } // CHECK-LABEL: @vfcmp_cule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cule.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cule.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cule_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cule_s(_1, _2); } // CHECK-LABEL: @vfcmp_cult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cult.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cult.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cult_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cult_d(_1, _2); } // CHECK-LABEL: @vfcmp_cult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cult.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cult.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cult_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cult_s(_1, _2); } // CHECK-LABEL: @vfcmp_cun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cun.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cun.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cun_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cun_d(_1, _2); } // CHECK-LABEL: @vfcmp_cune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cune.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cune.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cune_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_cune_d(_1, _2); } // CHECK-LABEL: @vfcmp_cune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cune.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cune.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cune_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cune_s(_1, _2); } // CHECK-LABEL: @vfcmp_cun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cun.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cun.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cun_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_cun_s(_1, _2); } // CHECK-LABEL: @vfcmp_saf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.saf.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.saf.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_saf_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_saf_d(_1, _2); } // CHECK-LABEL: @vfcmp_saf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.saf.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.saf.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_saf_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_saf_s(_1, _2); } // CHECK-LABEL: @vfcmp_seq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.seq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.seq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_seq_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_seq_d(_1, _2); } // CHECK-LABEL: @vfcmp_seq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.seq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.seq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_seq_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_seq_s(_1, _2); } // CHECK-LABEL: @vfcmp_sle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sle.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sle.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sle_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sle_d(_1, _2); } // CHECK-LABEL: @vfcmp_sle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sle.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sle.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sle_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sle_s(_1, _2); } // CHECK-LABEL: @vfcmp_slt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.slt.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.slt.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_slt_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_slt_d(_1, _2); } // CHECK-LABEL: @vfcmp_slt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.slt.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.slt.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_slt_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_slt_s(_1, _2); } // CHECK-LABEL: @vfcmp_sne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sne.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sne.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sne_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sne_d(_1, _2); } // CHECK-LABEL: @vfcmp_sne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sne.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sne.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sne_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sne_s(_1, _2); } // CHECK-LABEL: @vfcmp_sor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sor.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sor.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sor_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sor_d(_1, _2); } // CHECK-LABEL: @vfcmp_sor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sor.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sor.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sor_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sor_s(_1, _2); } // CHECK-LABEL: @vfcmp_sueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sueq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sueq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sueq_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sueq_d(_1, _2); } // CHECK-LABEL: @vfcmp_sueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sueq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sueq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sueq_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sueq_s(_1, _2); } // CHECK-LABEL: @vfcmp_sule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sule.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sule.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sule_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sule_d(_1, _2); } // CHECK-LABEL: @vfcmp_sule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sule.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sule.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sule_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sule_s(_1, _2); } // CHECK-LABEL: @vfcmp_sult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sult.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sult.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sult_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sult_d(_1, _2); } // CHECK-LABEL: @vfcmp_sult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sult.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sult.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sult_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sult_s(_1, _2); } // CHECK-LABEL: @vfcmp_sun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sun.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sun.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sun_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sun_d(_1, _2); } // CHECK-LABEL: @vfcmp_sune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sune.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sune.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sune_d(v2f64 _1, v2f64 _2) { return __lsx_vfcmp_sune_d(_1, _2); } // CHECK-LABEL: @vfcmp_sune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sune.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sune.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sune_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sune_s(_1, _2); } // CHECK-LABEL: @vfcmp_sun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sun.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sun.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sun_s(v4f32 _1, v4f32 _2) { return __lsx_vfcmp_sun_s(_1, _2); } // CHECK-LABEL: @vrepli_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vrepli_b() { return __lsx_vrepli_b(1); } // CHECK-LABEL: @vrepli_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vrepli_d() { return __lsx_vrepli_d(1); } // CHECK-LABEL: @vrepli_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v8i16 vrepli_h() { return __lsx_vrepli_h(1); } // CHECK-LABEL: @vrepli_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v4i32 vrepli_w() { return __lsx_vrepli_w(1); } diff --git a/clang/test/CodeGen/LoongArch/lsx/builtin.c b/clang/test/CodeGen/LoongArch/lsx/builtin.c index ef5a390e1838c87f3468eee0cc14825bcde920c6..05a3d13a7fb9aeb9eb089f9ad49167a31e633754 100644 --- a/clang/test/CodeGen/LoongArch/lsx/builtin.c +++ b/clang/test/CodeGen/LoongArch/lsx/builtin.c @@ -29,3319 +29,4547 @@ typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__)); // CHECK-LABEL: @vsll_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsll.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsll.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsll_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsll_b(_1, _2); } // CHECK-LABEL: @vsll_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsll.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsll.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsll_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsll_h(_1, _2); } // CHECK-LABEL: @vsll_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsll.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsll.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsll_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsll_w(_1, _2); } // CHECK-LABEL: @vsll_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsll.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsll.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsll_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsll_d(_1, _2); } // CHECK-LABEL: @vslli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslli_b(v16i8 _1) { return __builtin_lsx_vslli_b(_1, 1); } // CHECK-LABEL: @vslli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslli_h(v8i16 _1) { return __builtin_lsx_vslli_h(_1, 1); } // CHECK-LABEL: @vslli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslli_w(v4i32 _1) { return __builtin_lsx_vslli_w(_1, 1); } // CHECK-LABEL: @vslli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslli_d(v2i64 _1) { return __builtin_lsx_vslli_d(_1, 1); } // CHECK-LABEL: @vsra_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsra.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsra.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsra_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsra_b(_1, _2); } // CHECK-LABEL: @vsra_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsra.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsra.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsra_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsra_h(_1, _2); } // CHECK-LABEL: @vsra_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsra.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsra.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsra_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsra_w(_1, _2); } // CHECK-LABEL: @vsra_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsra.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsra.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsra_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsra_d(_1, _2); } // CHECK-LABEL: @vsrai_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrai_b(v16i8 _1) { return __builtin_lsx_vsrai_b(_1, 1); } // CHECK-LABEL: @vsrai_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrai_h(v8i16 _1) { return __builtin_lsx_vsrai_h(_1, 1); } // CHECK-LABEL: @vsrai_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrai_w(v4i32 _1) { return __builtin_lsx_vsrai_w(_1, 1); } // CHECK-LABEL: @vsrai_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrai_d(v2i64 _1) { return __builtin_lsx_vsrai_d(_1, 1); } // CHECK-LABEL: @vsrar_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrar.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrar.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrar_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrar_b(_1, _2); } // CHECK-LABEL: @vsrar_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrar.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrar.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrar_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrar_h(_1, _2); } // CHECK-LABEL: @vsrar_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrar.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrar.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrar_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrar_w(_1, _2); } // CHECK-LABEL: @vsrar_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrar.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrar.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrar_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrar_d(_1, _2); } // CHECK-LABEL: @vsrari_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrari_b(v16i8 _1) { return __builtin_lsx_vsrari_b(_1, 1); } // CHECK-LABEL: @vsrari_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrari_h(v8i16 _1) { return __builtin_lsx_vsrari_h(_1, 1); } // CHECK-LABEL: @vsrari_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrari_w(v4i32 _1) { return __builtin_lsx_vsrari_w(_1, 1); } // CHECK-LABEL: @vsrari_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrari_d(v2i64 _1) { return __builtin_lsx_vsrari_d(_1, 1); } // CHECK-LABEL: @vsrl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrl.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrl.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrl_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrl_b(_1, _2); } // CHECK-LABEL: @vsrl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrl.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrl.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrl_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrl_h(_1, _2); } // CHECK-LABEL: @vsrl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrl.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrl.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrl_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrl_w(_1, _2); } // CHECK-LABEL: @vsrl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrl.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrl.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrl_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrl_d(_1, _2); } // CHECK-LABEL: @vsrli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrli_b(v16i8 _1) { return __builtin_lsx_vsrli_b(_1, 1); } // CHECK-LABEL: @vsrli_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrli_h(v8i16 _1) { return __builtin_lsx_vsrli_h(_1, 1); } // CHECK-LABEL: @vsrli_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrli_w(v4i32 _1) { return __builtin_lsx_vsrli_w(_1, 1); } // CHECK-LABEL: @vsrli_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrli_d(v2i64 _1) { return __builtin_lsx_vsrli_d(_1, 1); } // CHECK-LABEL: @vsrlr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlr_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrlr_b(_1, _2); } // CHECK-LABEL: @vsrlr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlr_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrlr_h(_1, _2); } // CHECK-LABEL: @vsrlr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlr_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrlr_w(_1, _2); } // CHECK-LABEL: @vsrlr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrlr_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrlr_d(_1, _2); } // CHECK-LABEL: @vsrlri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsrlri_b(v16i8 _1) { return __builtin_lsx_vsrlri_b(_1, 1); } // CHECK-LABEL: @vsrlri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsrlri_h(v8i16 _1) { return __builtin_lsx_vsrlri_h(_1, 1); } // CHECK-LABEL: @vsrlri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsrlri_w(v4i32 _1) { return __builtin_lsx_vsrlri_w(_1, 1); } // CHECK-LABEL: @vsrlri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsrlri_d(v2i64 _1) { return __builtin_lsx_vsrlri_d(_1, 1); } // CHECK-LABEL: @vbitclr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitclr_b(v16u8 _1, v16u8 _2) { return __builtin_lsx_vbitclr_b(_1, _2); } // CHECK-LABEL: @vbitclr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vbitclr_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vbitclr_h(_1, _2); } // CHECK-LABEL: @vbitclr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vbitclr_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vbitclr_w(_1, _2); } // CHECK-LABEL: @vbitclr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vbitclr_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vbitclr_d(_1, _2); } // CHECK-LABEL: @vbitclri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vbitclri_b(v16u8 _1) { return __builtin_lsx_vbitclri_b(_1, 1); } // CHECK-LABEL: @vbitclri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vbitclri_h(v8u16 _1) { return __builtin_lsx_vbitclri_h(_1, 1); } // CHECK-LABEL: @vbitclri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vbitclri_w(v4u32 _1) { return __builtin_lsx_vbitclri_w(_1, 1); } // CHECK-LABEL: @vbitclri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vbitclri_d(v2u64 _1) { return __builtin_lsx_vbitclri_d(_1, 1); } // CHECK-LABEL: @vbitset_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitset.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitset.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitset_b(v16u8 _1, v16u8 _2) { return __builtin_lsx_vbitset_b(_1, _2); } // CHECK-LABEL: @vbitset_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitset.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitset.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vbitset_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vbitset_h(_1, _2); } // CHECK-LABEL: @vbitset_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitset.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitset.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vbitset_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vbitset_w(_1, _2); } // CHECK-LABEL: @vbitset_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitset.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitset.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vbitset_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vbitset_d(_1, _2); } // CHECK-LABEL: @vbitseti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vbitseti_b(v16u8 _1) { return __builtin_lsx_vbitseti_b(_1, 1); } // CHECK-LABEL: @vbitseti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vbitseti_h(v8u16 _1) { return __builtin_lsx_vbitseti_h(_1, 1); } // CHECK-LABEL: @vbitseti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vbitseti_w(v4u32 _1) { return __builtin_lsx_vbitseti_w(_1, 1); } // CHECK-LABEL: @vbitseti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vbitseti_d(v2u64 _1) { return __builtin_lsx_vbitseti_d(_1, 1); } // CHECK-LABEL: @vbitrev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrev.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrev.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitrev_b(v16u8 _1, v16u8 _2) { return __builtin_lsx_vbitrev_b(_1, _2); } // CHECK-LABEL: @vbitrev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrev.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrev.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vbitrev_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vbitrev_h(_1, _2); } // CHECK-LABEL: @vbitrev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrev.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrev.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vbitrev_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vbitrev_w(_1, _2); } // CHECK-LABEL: @vbitrev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrev.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrev.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vbitrev_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vbitrev_d(_1, _2); } // CHECK-LABEL: @vbitrevi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vbitrevi_b(v16u8 _1) { return __builtin_lsx_vbitrevi_b(_1, 1); } // CHECK-LABEL: @vbitrevi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vbitrevi_h(v8u16 _1) { return __builtin_lsx_vbitrevi_h(_1, 1); } // CHECK-LABEL: @vbitrevi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vbitrevi_w(v4u32 _1) { return __builtin_lsx_vbitrevi_w(_1, 1); } // CHECK-LABEL: @vbitrevi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vbitrevi_d(v2u64 _1) { return __builtin_lsx_vbitrevi_d(_1, 1); } // CHECK-LABEL: @vadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vadd_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vadd_b(_1, _2); } // CHECK-LABEL: @vadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vadd_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vadd_h(_1, _2); } // CHECK-LABEL: @vadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vadd_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vadd_w(_1, _2); } // CHECK-LABEL: @vadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vadd_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vadd_d(_1, _2); } // CHECK-LABEL: @vaddi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vaddi_bu(v16i8 _1) { return __builtin_lsx_vaddi_bu(_1, 1); } // CHECK-LABEL: @vaddi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vaddi_hu(v8i16 _1) { return __builtin_lsx_vaddi_hu(_1, 1); } // CHECK-LABEL: @vaddi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vaddi_wu(v4i32 _1) { return __builtin_lsx_vaddi_wu(_1, 1); } // CHECK-LABEL: @vaddi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vaddi_du(v2i64 _1) { return __builtin_lsx_vaddi_du(_1, 1); } // CHECK-LABEL: @vsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsub.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsub.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsub_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsub_b(_1, _2); } // CHECK-LABEL: @vsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsub.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsub.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsub_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsub_h(_1, _2); } // CHECK-LABEL: @vsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsub_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsub_w(_1, _2); } // CHECK-LABEL: @vsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsub_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsub_d(_1, _2); } // CHECK-LABEL: @vsubi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsubi_bu(v16i8 _1) { return __builtin_lsx_vsubi_bu(_1, 1); } // CHECK-LABEL: @vsubi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsubi_hu(v8i16 _1) { return __builtin_lsx_vsubi_hu(_1, 1); } // CHECK-LABEL: @vsubi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsubi_wu(v4i32 _1) { return __builtin_lsx_vsubi_wu(_1, 1); } // CHECK-LABEL: @vsubi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsubi_du(v2i64 _1) { return __builtin_lsx_vsubi_du(_1, 1); } // CHECK-LABEL: @vmax_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmax_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmax_b(_1, _2); } // CHECK-LABEL: @vmax_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmax_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmax_h(_1, _2); } // CHECK-LABEL: @vmax_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmax_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmax_w(_1, _2); } // CHECK-LABEL: @vmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmax_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmax_d(_1, _2); } // CHECK-LABEL: @vmaxi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmaxi_b(v16i8 _1) { return __builtin_lsx_vmaxi_b(_1, 1); } // CHECK-LABEL: @vmaxi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vmaxi_h(v8i16 _1) { return __builtin_lsx_vmaxi_h(_1, 1); } // CHECK-LABEL: @vmaxi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vmaxi_w(v4i32 _1) { return __builtin_lsx_vmaxi_w(_1, 1); } // CHECK-LABEL: @vmaxi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vmaxi_d(v2i64 _1) { return __builtin_lsx_vmaxi_d(_1, 1); } // CHECK-LABEL: @vmax_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmax.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmax_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vmax_bu(_1, _2); } // CHECK-LABEL: @vmax_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmax.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmax_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vmax_hu(_1, _2); } // CHECK-LABEL: @vmax_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmax.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmax_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vmax_wu(_1, _2); } // CHECK-LABEL: @vmax_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmax.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmax_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vmax_du(_1, _2); } // CHECK-LABEL: @vmaxi_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vmaxi_bu(v16u8 _1) { return __builtin_lsx_vmaxi_bu(_1, 1); } // CHECK-LABEL: @vmaxi_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vmaxi_hu(v8u16 _1) { return __builtin_lsx_vmaxi_hu(_1, 1); } // CHECK-LABEL: @vmaxi_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vmaxi_wu(v4u32 _1) { return __builtin_lsx_vmaxi_wu(_1, 1); } // CHECK-LABEL: @vmaxi_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vmaxi_du(v2u64 _1) { return __builtin_lsx_vmaxi_du(_1, 1); } // CHECK-LABEL: @vmin_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmin_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmin_b(_1, _2); } // CHECK-LABEL: @vmin_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmin_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmin_h(_1, _2); } // CHECK-LABEL: @vmin_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmin_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmin_w(_1, _2); } // CHECK-LABEL: @vmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmin_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmin_d(_1, _2); } // CHECK-LABEL: @vmini_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmini_b(v16i8 _1) { return __builtin_lsx_vmini_b(_1, 1); } // CHECK-LABEL: @vmini_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vmini_h(v8i16 _1) { return __builtin_lsx_vmini_h(_1, 1); } // CHECK-LABEL: @vmini_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vmini_w(v4i32 _1) { return __builtin_lsx_vmini_w(_1, 1); } // CHECK-LABEL: @vmini_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vmini_d(v2i64 _1) { return __builtin_lsx_vmini_d(_1, 1); } // CHECK-LABEL: @vmin_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmin.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmin_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vmin_bu(_1, _2); } // CHECK-LABEL: @vmin_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmin.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmin_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vmin_hu(_1, _2); } // CHECK-LABEL: @vmin_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmin.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmin_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vmin_wu(_1, _2); } // CHECK-LABEL: @vmin_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmin.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmin_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vmin_du(_1, _2); } // CHECK-LABEL: @vmini_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vmini_bu(v16u8 _1) { return __builtin_lsx_vmini_bu(_1, 1); } // CHECK-LABEL: @vmini_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vmini_hu(v8u16 _1) { return __builtin_lsx_vmini_hu(_1, 1); } // CHECK-LABEL: @vmini_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vmini_wu(v4u32 _1) { return __builtin_lsx_vmini_wu(_1, 1); } // CHECK-LABEL: @vmini_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vmini_du(v2u64 _1) { return __builtin_lsx_vmini_du(_1, 1); } // CHECK-LABEL: @vseq_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseq.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseq.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vseq_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vseq_b(_1, _2); } // CHECK-LABEL: @vseq_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseq.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseq.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vseq_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vseq_h(_1, _2); } // CHECK-LABEL: @vseq_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseq.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseq.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vseq_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vseq_w(_1, _2); } // CHECK-LABEL: @vseq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseq.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseq.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vseq_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vseq_d(_1, _2); } // CHECK-LABEL: @vseqi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vseqi_b(v16i8 _1) { return __builtin_lsx_vseqi_b(_1, 1); } // CHECK-LABEL: @vseqi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vseqi_h(v8i16 _1) { return __builtin_lsx_vseqi_h(_1, 1); } // CHECK-LABEL: @vseqi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vseqi_w(v4i32 _1) { return __builtin_lsx_vseqi_w(_1, 1); } // CHECK-LABEL: @vseqi_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vseqi_d(v2i64 _1) { return __builtin_lsx_vseqi_d(_1, 1); } // CHECK-LABEL: @vslti_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslti_b(v16i8 _1) { return __builtin_lsx_vslti_b(_1, 1); } // CHECK-LABEL: @vslt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vslt_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vslt_b(_1, _2); } // CHECK-LABEL: @vslt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vslt_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vslt_h(_1, _2); } // CHECK-LABEL: @vslt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vslt_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vslt_w(_1, _2); } // CHECK-LABEL: @vslt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vslt_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vslt_d(_1, _2); } // CHECK-LABEL: @vslti_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslti_h(v8i16 _1) { return __builtin_lsx_vslti_h(_1, 1); } // CHECK-LABEL: @vslti_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslti_w(v4i32 _1) { return __builtin_lsx_vslti_w(_1, 1); } // CHECK-LABEL: @vslti_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslti_d(v2i64 _1) { return __builtin_lsx_vslti_d(_1, 1); } // CHECK-LABEL: @vslt_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslt.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vslt_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vslt_bu(_1, _2); } // CHECK-LABEL: @vslt_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslt.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vslt_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vslt_hu(_1, _2); } // CHECK-LABEL: @vslt_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslt.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vslt_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vslt_wu(_1, _2); } // CHECK-LABEL: @vslt_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslt.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vslt_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vslt_du(_1, _2); } // CHECK-LABEL: @vslti_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslti_bu(v16u8 _1) { return __builtin_lsx_vslti_bu(_1, 1); } // CHECK-LABEL: @vslti_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslti_hu(v8u16 _1) { return __builtin_lsx_vslti_hu(_1, 1); } // CHECK-LABEL: @vslti_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslti_wu(v4u32 _1) { return __builtin_lsx_vslti_wu(_1, 1); } // CHECK-LABEL: @vslti_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslti_du(v2u64 _1) { return __builtin_lsx_vslti_du(_1, 1); } // CHECK-LABEL: @vsle_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsle_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsle_b(_1, _2); } // CHECK-LABEL: @vsle_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsle_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsle_h(_1, _2); } // CHECK-LABEL: @vsle_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsle_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsle_w(_1, _2); } // CHECK-LABEL: @vsle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsle_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsle_d(_1, _2); } // CHECK-LABEL: @vslei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslei_b(v16i8 _1) { return __builtin_lsx_vslei_b(_1, 1); } // CHECK-LABEL: @vslei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslei_h(v8i16 _1) { return __builtin_lsx_vslei_h(_1, 1); } // CHECK-LABEL: @vslei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslei_w(v4i32 _1) { return __builtin_lsx_vslei_w(_1, 1); } // CHECK-LABEL: @vslei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslei_d(v2i64 _1) { return __builtin_lsx_vslei_d(_1, 1); } // CHECK-LABEL: @vsle_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsle.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsle_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vsle_bu(_1, _2); } // CHECK-LABEL: @vsle_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsle.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsle_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vsle_hu(_1, _2); } // CHECK-LABEL: @vsle_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsle.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsle_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vsle_wu(_1, _2); } // CHECK-LABEL: @vsle_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsle.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsle_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vsle_du(_1, _2); } // CHECK-LABEL: @vslei_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vslei_bu(v16u8 _1) { return __builtin_lsx_vslei_bu(_1, 1); } // CHECK-LABEL: @vslei_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vslei_hu(v8u16 _1) { return __builtin_lsx_vslei_hu(_1, 1); } // CHECK-LABEL: @vslei_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vslei_wu(v4u32 _1) { return __builtin_lsx_vslei_wu(_1, 1); } // CHECK-LABEL: @vslei_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vslei_du(v2u64 _1) { return __builtin_lsx_vslei_du(_1, 1); } // CHECK-LABEL: @vsat_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vsat_b(v16i8 _1) { return __builtin_lsx_vsat_b(_1, 1); } // CHECK-LABEL: @vsat_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsat_h(v8i16 _1) { return __builtin_lsx_vsat_h(_1, 1); } // CHECK-LABEL: @vsat_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsat_w(v4i32 _1) { return __builtin_lsx_vsat_w(_1, 1); } // CHECK-LABEL: @vsat_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsat_d(v2i64 _1) { return __builtin_lsx_vsat_d(_1, 1); } // CHECK-LABEL: @vsat_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vsat_bu(v16u8 _1) { return __builtin_lsx_vsat_bu(_1, 1); } // CHECK-LABEL: @vsat_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vsat_hu(v8u16 _1) { return __builtin_lsx_vsat_hu(_1, 1); } // CHECK-LABEL: @vsat_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vsat_wu(v4u32 _1) { return __builtin_lsx_vsat_wu(_1, 1); } // CHECK-LABEL: @vsat_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vsat_du(v2u64 _1) { return __builtin_lsx_vsat_du(_1, 1); } // CHECK-LABEL: @vadda_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadda.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vadda.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vadda_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vadda_b(_1, _2); } // CHECK-LABEL: @vadda_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadda.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vadda.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vadda_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vadda_h(_1, _2); } // CHECK-LABEL: @vadda_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadda.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vadda.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vadda_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vadda_w(_1, _2); } // CHECK-LABEL: @vadda_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadda.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadda.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vadda_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vadda_d(_1, _2); } // CHECK-LABEL: @vsadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsadd_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsadd_b(_1, _2); } // CHECK-LABEL: @vsadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsadd_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsadd_h(_1, _2); } // CHECK-LABEL: @vsadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsadd_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsadd_w(_1, _2); } // CHECK-LABEL: @vsadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsadd_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsadd_d(_1, _2); } // CHECK-LABEL: @vsadd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsadd.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vsadd_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vsadd_bu(_1, _2); } // CHECK-LABEL: @vsadd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsadd.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vsadd_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vsadd_hu(_1, _2); } // CHECK-LABEL: @vsadd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsadd.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vsadd_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vsadd_wu(_1, _2); } // CHECK-LABEL: @vsadd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsadd.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vsadd_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vsadd_du(_1, _2); } // CHECK-LABEL: @vavg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vavg_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vavg_b(_1, _2); } // CHECK-LABEL: @vavg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vavg_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vavg_h(_1, _2); } // CHECK-LABEL: @vavg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vavg_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vavg_w(_1, _2); } // CHECK-LABEL: @vavg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vavg_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vavg_d(_1, _2); } // CHECK-LABEL: @vavg_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavg.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vavg_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vavg_bu(_1, _2); } // CHECK-LABEL: @vavg_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavg.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vavg_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vavg_hu(_1, _2); } // CHECK-LABEL: @vavg_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavg.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vavg_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vavg_wu(_1, _2); } // CHECK-LABEL: @vavg_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavg.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vavg_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vavg_du(_1, _2); } // CHECK-LABEL: @vavgr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vavgr_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vavgr_b(_1, _2); } // CHECK-LABEL: @vavgr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vavgr_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vavgr_h(_1, _2); } // CHECK-LABEL: @vavgr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vavgr_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vavgr_w(_1, _2); } // CHECK-LABEL: @vavgr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vavgr_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vavgr_d(_1, _2); } // CHECK-LABEL: @vavgr_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vavgr.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vavgr_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vavgr_bu(_1, _2); } // CHECK-LABEL: @vavgr_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vavgr.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vavgr_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vavgr_hu(_1, _2); } // CHECK-LABEL: @vavgr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vavgr.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vavgr_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vavgr_wu(_1, _2); } // CHECK-LABEL: @vavgr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vavgr.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vavgr_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vavgr_du(_1, _2); } // CHECK-LABEL: @vssub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssub_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vssub_b(_1, _2); } // CHECK-LABEL: @vssub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssub_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssub_h(_1, _2); } // CHECK-LABEL: @vssub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssub_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssub_w(_1, _2); } // CHECK-LABEL: @vssub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssub_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssub_d(_1, _2); } // CHECK-LABEL: @vssub_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssub.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssub_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vssub_bu(_1, _2); } // CHECK-LABEL: @vssub_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssub.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssub_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vssub_hu(_1, _2); } // CHECK-LABEL: @vssub_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssub.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssub_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vssub_wu(_1, _2); } // CHECK-LABEL: @vssub_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssub.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssub_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vssub_du(_1, _2); } // CHECK-LABEL: @vabsd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vabsd_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vabsd_b(_1, _2); } // CHECK-LABEL: @vabsd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vabsd_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vabsd_h(_1, _2); } // CHECK-LABEL: @vabsd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vabsd_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vabsd_w(_1, _2); } // CHECK-LABEL: @vabsd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vabsd_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vabsd_d(_1, _2); } // CHECK-LABEL: @vabsd_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vabsd.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vabsd_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vabsd_bu(_1, _2); } // CHECK-LABEL: @vabsd_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vabsd.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vabsd_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vabsd_hu(_1, _2); } // CHECK-LABEL: @vabsd_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vabsd.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vabsd_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vabsd_wu(_1, _2); } // CHECK-LABEL: @vabsd_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vabsd.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vabsd_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vabsd_du(_1, _2); } // CHECK-LABEL: @vmul_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmul.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmul.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmul_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmul_b(_1, _2); } // CHECK-LABEL: @vmul_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmul.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmul.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmul_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmul_h(_1, _2); } // CHECK-LABEL: @vmul_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmul.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmul.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmul_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmul_w(_1, _2); } // CHECK-LABEL: @vmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmul.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmul.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmul_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmul_d(_1, _2); } // CHECK-LABEL: @vmadd_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmadd.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmadd.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vmadd_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __builtin_lsx_vmadd_b(_1, _2, _3); } // CHECK-LABEL: @vmadd_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmadd.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmadd.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmadd_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __builtin_lsx_vmadd_h(_1, _2, _3); } // CHECK-LABEL: @vmadd_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmadd.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmadd.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmadd_w(v4i32 _1, v4i32 _2, v4i32 _3) { return __builtin_lsx_vmadd_w(_1, _2, _3); } // CHECK-LABEL: @vmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmadd.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmadd.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmadd_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __builtin_lsx_vmadd_d(_1, _2, _3); } // CHECK-LABEL: @vmsub_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsub.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsub.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vmsub_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __builtin_lsx_vmsub_b(_1, _2, _3); } // CHECK-LABEL: @vmsub_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmsub.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmsub.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmsub_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __builtin_lsx_vmsub_h(_1, _2, _3); } // CHECK-LABEL: @vmsub_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmsub.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmsub.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmsub_w(v4i32 _1, v4i32 _2, v4i32 _3) { return __builtin_lsx_vmsub_w(_1, _2, _3); } // CHECK-LABEL: @vmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmsub.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmsub.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmsub_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __builtin_lsx_vmsub_d(_1, _2, _3); } // CHECK-LABEL: @vdiv_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vdiv_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vdiv_b(_1, _2); } // CHECK-LABEL: @vdiv_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vdiv_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vdiv_h(_1, _2); } // CHECK-LABEL: @vdiv_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vdiv_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vdiv_w(_1, _2); } // CHECK-LABEL: @vdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vdiv_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vdiv_d(_1, _2); } // CHECK-LABEL: @vdiv_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vdiv.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vdiv_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vdiv_bu(_1, _2); } // CHECK-LABEL: @vdiv_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vdiv.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vdiv_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vdiv_hu(_1, _2); } // CHECK-LABEL: @vdiv_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vdiv.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vdiv_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vdiv_wu(_1, _2); } // CHECK-LABEL: @vdiv_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vdiv.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vdiv_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vdiv_du(_1, _2); } // CHECK-LABEL: @vhaddw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vhaddw_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vhaddw_h_b(_1, _2); } // CHECK-LABEL: @vhaddw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vhaddw_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vhaddw_w_h(_1, _2); } // CHECK-LABEL: @vhaddw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhaddw_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vhaddw_d_w(_1, _2); } // CHECK-LABEL: @vhaddw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.hu.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhaddw.hu.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vhaddw_hu_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vhaddw_hu_bu(_1, _2); } // CHECK-LABEL: @vhaddw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.wu.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhaddw.wu.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vhaddw_wu_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vhaddw_wu_hu(_1, _2); } // CHECK-LABEL: @vhaddw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.du.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.du.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vhaddw_du_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vhaddw_du_wu(_1, _2); } // CHECK-LABEL: @vhsubw_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vhsubw_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vhsubw_h_b(_1, _2); } // CHECK-LABEL: @vhsubw_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vhsubw_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vhsubw_w_h(_1, _2); } // CHECK-LABEL: @vhsubw_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhsubw_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vhsubw_d_w(_1, _2); } // CHECK-LABEL: @vhsubw_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.hu.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vhsubw.hu.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vhsubw_hu_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vhsubw_hu_bu(_1, _2); } // CHECK-LABEL: @vhsubw_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.wu.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vhsubw.wu.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vhsubw_wu_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vhsubw_wu_hu(_1, _2); } // CHECK-LABEL: @vhsubw_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.du.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.du.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhsubw_du_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vhsubw_du_wu(_1, _2); } // CHECK-LABEL: @vmod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmod_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmod_b(_1, _2); } // CHECK-LABEL: @vmod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmod_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmod_h(_1, _2); } // CHECK-LABEL: @vmod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmod_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmod_w(_1, _2); } // CHECK-LABEL: @vmod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmod_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmod_d(_1, _2); } // CHECK-LABEL: @vmod_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmod.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmod_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vmod_bu(_1, _2); } // CHECK-LABEL: @vmod_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmod.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmod_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vmod_hu(_1, _2); } // CHECK-LABEL: @vmod_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmod.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmod_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vmod_wu(_1, _2); } // CHECK-LABEL: @vmod_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmod.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmod_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vmod_du(_1, _2); } // CHECK-LABEL: @vreplve_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplve.b(<16 x i8> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplve.b(<16 x i8> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vreplve_b(v16i8 _1, int _2) { return __builtin_lsx_vreplve_b(_1, _2); } // CHECK-LABEL: @vreplve_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplve.h(<8 x i16> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplve.h(<8 x i16> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vreplve_h(v8i16 _1, int _2) { return __builtin_lsx_vreplve_h(_1, _2); } // CHECK-LABEL: @vreplve_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplve.w(<4 x i32> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplve.w(<4 x i32> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vreplve_w(v4i32 _1, int _2) { return __builtin_lsx_vreplve_w(_1, _2); } // CHECK-LABEL: @vreplve_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplve.d(<2 x i64> [[_1:%.*]], i32 [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplve.d(<2 x i64> [[TMP0]], i32 [[_2:%.*]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vreplve_d(v2i64 _1, int _2) { return __builtin_lsx_vreplve_d(_1, _2); } // CHECK-LABEL: @vreplvei_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vreplvei_b(v16i8 _1) { return __builtin_lsx_vreplvei_b(_1, 1); } // CHECK-LABEL: @vreplvei_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vreplvei_h(v8i16 _1) { return __builtin_lsx_vreplvei_h(_1, 1); } // CHECK-LABEL: @vreplvei_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vreplvei_w(v4i32 _1) { return __builtin_lsx_vreplvei_w(_1, 1); } // CHECK-LABEL: @vreplvei_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vreplvei_d(v2i64 _1) { return __builtin_lsx_vreplvei_d(_1, 1); } // CHECK-LABEL: @vpickev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickev.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickev.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpickev_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vpickev_b(_1, _2); } // CHECK-LABEL: @vpickev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickev.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickev.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpickev_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vpickev_h(_1, _2); } // CHECK-LABEL: @vpickev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickev.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickev.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpickev_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vpickev_w(_1, _2); } // CHECK-LABEL: @vpickev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickev.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickev.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpickev_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vpickev_d(_1, _2); } // CHECK-LABEL: @vpickod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickod.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpickod.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpickod_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vpickod_b(_1, _2); } // CHECK-LABEL: @vpickod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickod.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpickod.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpickod_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vpickod_h(_1, _2); } // CHECK-LABEL: @vpickod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickod.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpickod.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpickod_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vpickod_w(_1, _2); } // CHECK-LABEL: @vpickod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickod.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpickod.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpickod_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vpickod_d(_1, _2); } // CHECK-LABEL: @vilvh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvh.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvh.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vilvh_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vilvh_b(_1, _2); } // CHECK-LABEL: @vilvh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvh.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvh.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vilvh_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vilvh_h(_1, _2); } // CHECK-LABEL: @vilvh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvh.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvh.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vilvh_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vilvh_w(_1, _2); } // CHECK-LABEL: @vilvh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvh.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvh.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vilvh_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vilvh_d(_1, _2); } // CHECK-LABEL: @vilvl_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvl.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vilvl.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vilvl_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vilvl_b(_1, _2); } // CHECK-LABEL: @vilvl_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvl.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vilvl.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vilvl_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vilvl_h(_1, _2); } // CHECK-LABEL: @vilvl_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvl.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vilvl.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vilvl_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vilvl_w(_1, _2); } // CHECK-LABEL: @vilvl_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvl.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vilvl.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vilvl_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vilvl_d(_1, _2); } // CHECK-LABEL: @vpackev_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackev.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackev.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpackev_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vpackev_b(_1, _2); } // CHECK-LABEL: @vpackev_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackev.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackev.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpackev_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vpackev_h(_1, _2); } // CHECK-LABEL: @vpackev_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackev.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackev.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpackev_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vpackev_w(_1, _2); } // CHECK-LABEL: @vpackev_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackev.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackev.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpackev_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vpackev_d(_1, _2); } // CHECK-LABEL: @vpackod_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackod.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpackod.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vpackod_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vpackod_b(_1, _2); } // CHECK-LABEL: @vpackod_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackod.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpackod.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vpackod_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vpackod_h(_1, _2); } // CHECK-LABEL: @vpackod_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackod.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpackod.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpackod_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vpackod_w(_1, _2); } // CHECK-LABEL: @vpackod_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackod.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpackod.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vpackod_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vpackod_d(_1, _2); } // CHECK-LABEL: @vshuf_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vshuf_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __builtin_lsx_vshuf_h(_1, _2, _3); } // CHECK-LABEL: @vshuf_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vshuf_w(v4i32 _1, v4i32 _2, v4i32 _3) { return __builtin_lsx_vshuf_w(_1, _2, _3); } // CHECK-LABEL: @vshuf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vshuf_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __builtin_lsx_vshuf_d(_1, _2, _3); } // CHECK-LABEL: @vand_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vand.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vand.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vand_v(v16u8 _1, v16u8 _2) { return __builtin_lsx_vand_v(_1, _2); } // CHECK-LABEL: @vandi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vandi_b(v16u8 _1) { return __builtin_lsx_vandi_b(_1, 1); } // CHECK-LABEL: @vor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vor.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vor.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vor_v(v16u8 _1, v16u8 _2) { return __builtin_lsx_vor_v(_1, _2); } // CHECK-LABEL: @vori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vori_b(v16u8 _1) { return __builtin_lsx_vori_b(_1, 1); } // CHECK-LABEL: @vnor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnor.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnor.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vnor_v(v16u8 _1, v16u8 _2) { return __builtin_lsx_vnor_v(_1, _2); } // CHECK-LABEL: @vnori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vnori_b(v16u8 _1) { return __builtin_lsx_vnori_b(_1, 1); } // CHECK-LABEL: @vxor_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxor.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxor.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vxor_v(v16u8 _1, v16u8 _2) { return __builtin_lsx_vxor_v(_1, _2); } // CHECK-LABEL: @vxori_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16u8 vxori_b(v16u8 _1) { return __builtin_lsx_vxori_b(_1, 1); } // CHECK-LABEL: @vbitsel_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitsel.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitsel.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16u8 vbitsel_v(v16u8 _1, v16u8 _2, v16u8 _3) { return __builtin_lsx_vbitsel_v(_1, _2, _3); } // CHECK-LABEL: @vbitseli_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vbitseli_b(v16u8 _1, v16u8 _2) { return __builtin_lsx_vbitseli_b(_1, _2, 1); } // CHECK-LABEL: @vshuf4i_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vshuf4i_b(v16i8 _1) { return __builtin_lsx_vshuf4i_b(_1, 1); } // CHECK-LABEL: @vshuf4i_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vshuf4i_h(v8i16 _1) { return __builtin_lsx_vshuf4i_h(_1, 1); } // CHECK-LABEL: @vshuf4i_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vshuf4i_w(v4i32 _1) { return __builtin_lsx_vshuf4i_w(_1, 1); } // CHECK-LABEL: @vreplgr2vr_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vreplgr2vr.b(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vreplgr2vr_b(int _1) { return __builtin_lsx_vreplgr2vr_b(_1); } // CHECK-LABEL: @vreplgr2vr_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vreplgr2vr.h(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v8i16 vreplgr2vr_h(int _1) { return __builtin_lsx_vreplgr2vr_h(_1); } // CHECK-LABEL: @vreplgr2vr_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vreplgr2vr.w(i32 [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v4i32 vreplgr2vr_w(int _1) { return __builtin_lsx_vreplgr2vr_w(_1); } // CHECK-LABEL: @vreplgr2vr_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vreplgr2vr.d(i64 [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vreplgr2vr_d(long _1) { return __builtin_lsx_vreplgr2vr_d(_1); } // CHECK-LABEL: @vpcnt_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpcnt.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vpcnt.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vpcnt_b(v16i8 _1) { return __builtin_lsx_vpcnt_b(_1); } // CHECK-LABEL: @vpcnt_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpcnt.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vpcnt.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vpcnt_h(v8i16 _1) { return __builtin_lsx_vpcnt_h(_1); } // CHECK-LABEL: @vpcnt_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpcnt.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpcnt.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vpcnt_w(v4i32 _1) { return __builtin_lsx_vpcnt_w(_1); } // CHECK-LABEL: @vpcnt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpcnt.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vpcnt.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vpcnt_d(v2i64 _1) { return __builtin_lsx_vpcnt_d(_1); } // CHECK-LABEL: @vclo_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclo.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclo.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vclo_b(v16i8 _1) { return __builtin_lsx_vclo_b(_1); } // CHECK-LABEL: @vclo_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclo.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclo.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vclo_h(v8i16 _1) { return __builtin_lsx_vclo_h(_1); } // CHECK-LABEL: @vclo_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclo.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclo.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vclo_w(v4i32 _1) { return __builtin_lsx_vclo_w(_1); } // CHECK-LABEL: @vclo_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclo.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclo.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vclo_d(v2i64 _1) { return __builtin_lsx_vclo_d(_1); } // CHECK-LABEL: @vclz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vclz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vclz_b(v16i8 _1) { return __builtin_lsx_vclz_b(_1); } // CHECK-LABEL: @vclz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vclz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vclz_h(v8i16 _1) { return __builtin_lsx_vclz_h(_1); } // CHECK-LABEL: @vclz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vclz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vclz_w(v4i32 _1) { return __builtin_lsx_vclz_w(_1); } // CHECK-LABEL: @vclz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vclz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vclz_d(v2i64 _1) { return __builtin_lsx_vclz_d(_1); } // CHECK-LABEL: @vpickve2gr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int vpickve2gr_b(v16i8 _1) { return __builtin_lsx_vpickve2gr_b(_1, 1); } // CHECK-LABEL: @vpickve2gr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int vpickve2gr_h(v8i16 _1) { return __builtin_lsx_vpickve2gr_h(_1, 1); } // CHECK-LABEL: @vpickve2gr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // int vpickve2gr_w(v4i32 _1) { return __builtin_lsx_vpickve2gr_w(_1, 1); } // CHECK-LABEL: @vpickve2gr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // long vpickve2gr_d(v2i64 _1) { return __builtin_lsx_vpickve2gr_d(_1, 1); } // CHECK-LABEL: @vpickve2gr_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int vpickve2gr_bu(v16i8 _1) { return __builtin_lsx_vpickve2gr_bu(_1, 1); } // CHECK-LABEL: @vpickve2gr_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int vpickve2gr_hu(v8i16 _1) { return __builtin_lsx_vpickve2gr_hu(_1, 1); } // CHECK-LABEL: @vpickve2gr_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: ret i32 [[TMP1]] // unsigned int vpickve2gr_wu(v4i32 _1) { return __builtin_lsx_vpickve2gr_wu(_1, 1); } // CHECK-LABEL: @vpickve2gr_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret i64 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: ret i64 [[TMP1]] // unsigned long int vpickve2gr_du(v2i64 _1) { return __builtin_lsx_vpickve2gr_du(_1, 1); } // CHECK-LABEL: @vinsgr2vr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> [[TMP0]], i32 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vinsgr2vr_b(v16i8 _1) { return __builtin_lsx_vinsgr2vr_b(_1, 1, 1); } // CHECK-LABEL: @vinsgr2vr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> [[TMP0]], i32 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vinsgr2vr_h(v8i16 _1) { return __builtin_lsx_vinsgr2vr_h(_1, 1, 1); } // CHECK-LABEL: @vinsgr2vr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> [[_1:%.*]], i32 1, i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> [[TMP0]], i32 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vinsgr2vr_w(v4i32 _1) { return __builtin_lsx_vinsgr2vr_w(_1, 1, 1); } // CHECK-LABEL: @vinsgr2vr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> [[_1:%.*]], i64 1, i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> [[TMP0]], i64 1, i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vinsgr2vr_d(v2i64 _1) { return __builtin_lsx_vinsgr2vr_d(_1, 1, 1); } // CHECK-LABEL: @vfadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfadd.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfadd.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfadd_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfadd_s(_1, _2); } // CHECK-LABEL: @vfadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfadd.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfadd.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfadd_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfadd_d(_1, _2); } // CHECK-LABEL: @vfsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsub.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsub.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfsub_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfsub_s(_1, _2); } // CHECK-LABEL: @vfsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsub.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsub.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfsub_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfsub_d(_1, _2); } // CHECK-LABEL: @vfmul_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmul.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmul.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmul_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfmul_s(_1, _2); } // CHECK-LABEL: @vfmul_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmul.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmul.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmul_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfmul_d(_1, _2); } // CHECK-LABEL: @vfdiv_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfdiv.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfdiv.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfdiv_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfdiv_s(_1, _2); } // CHECK-LABEL: @vfdiv_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfdiv.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfdiv.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfdiv_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfdiv_d(_1, _2); } // CHECK-LABEL: @vfcvt_h_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfcvt.h.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfcvt.h.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vfcvt_h_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcvt_h_s(_1, _2); } // CHECK-LABEL: @vfcvt_s_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvt.s.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvt.s.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfcvt_s_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcvt_s_d(_1, _2); } // CHECK-LABEL: @vfmin_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmin.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmin.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmin_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfmin_s(_1, _2); } // CHECK-LABEL: @vfmin_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmin.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmin.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmin_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfmin_d(_1, _2); } // CHECK-LABEL: @vfmina_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmina.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmina.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmina_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfmina_s(_1, _2); } // CHECK-LABEL: @vfmina_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmina.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmina.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmina_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfmina_d(_1, _2); } // CHECK-LABEL: @vfmax_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmax.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmax.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmax_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfmax_s(_1, _2); } // CHECK-LABEL: @vfmax_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmax.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmax.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmax_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfmax_d(_1, _2); } // CHECK-LABEL: @vfmaxa_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmaxa.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmaxa.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vfmaxa_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfmaxa_s(_1, _2); } // CHECK-LABEL: @vfmaxa_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmaxa.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmaxa.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2f64 vfmaxa_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfmaxa_d(_1, _2); } // CHECK-LABEL: @vfclass_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfclass.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfclass.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfclass_s(v4f32 _1) { return __builtin_lsx_vfclass_s(_1); } // CHECK-LABEL: @vfclass_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfclass.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfclass.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfclass_d(v2f64 _1) { return __builtin_lsx_vfclass_d(_1); } // CHECK-LABEL: @vfsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsqrt.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfsqrt.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfsqrt_s(v4f32 _1) { return __builtin_lsx_vfsqrt_s(_1); } // CHECK-LABEL: @vfsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsqrt.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfsqrt.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfsqrt_d(v2f64 _1) { return __builtin_lsx_vfsqrt_d(_1); } // CHECK-LABEL: @vfrecip_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrecip.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrecip.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfrecip_s(v4f32 _1) { return __builtin_lsx_vfrecip_s(_1); } // CHECK-LABEL: @vfrecip_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrecip.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrecip.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfrecip_d(v2f64 _1) { return __builtin_lsx_vfrecip_d(_1); } // CHECK-LABEL: @vfrint_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrint.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrint.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfrint_s(v4f32 _1) { return __builtin_lsx_vfrint_s(_1); } // CHECK-LABEL: @vfrint_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrint.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrint.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfrint_d(v2f64 _1) { return __builtin_lsx_vfrint_d(_1); } // CHECK-LABEL: @vfrsqrt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrsqrt.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrsqrt.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfrsqrt_s(v4f32 _1) { return __builtin_lsx_vfrsqrt_s(_1); } // CHECK-LABEL: @vfrsqrt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrsqrt.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrsqrt.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfrsqrt_d(v2f64 _1) { return __builtin_lsx_vfrsqrt_d(_1); } // CHECK-LABEL: @vflogb_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vflogb.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vflogb.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vflogb_s(v4f32 _1) { return __builtin_lsx_vflogb_s(_1); } // CHECK-LABEL: @vflogb_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vflogb.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vflogb.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vflogb_d(v2f64 _1) { return __builtin_lsx_vflogb_d(_1); } // CHECK-LABEL: @vfcvth_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvth.s.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvth.s.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfcvth_s_h(v8i16 _1) { return __builtin_lsx_vfcvth_s_h(_1); } // CHECK-LABEL: @vfcvth_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvth.d.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvth.d.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfcvth_d_s(v4f32 _1) { return __builtin_lsx_vfcvth_d_s(_1); } // CHECK-LABEL: @vfcvtl_s_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvtl.s.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfcvtl.s.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vfcvtl_s_h(v8i16 _1) { return __builtin_lsx_vfcvtl_s_h(_1); } // CHECK-LABEL: @vfcvtl_d_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvtl.d.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfcvtl.d.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vfcvtl_d_s(v4f32 _1) { return __builtin_lsx_vfcvtl_d_s(_1); } // CHECK-LABEL: @vftint_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftint_w_s(v4f32 _1) { return __builtin_lsx_vftint_w_s(_1); } // CHECK-LABEL: @vftint_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftint_l_d(v2f64 _1) { return __builtin_lsx_vftint_l_d(_1); } // CHECK-LABEL: @vftint_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.wu.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.wu.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vftint_wu_s(v4f32 _1) { return __builtin_lsx_vftint_wu_s(_1); } // CHECK-LABEL: @vftint_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.lu.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftint.lu.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vftint_lu_d(v2f64 _1) { return __builtin_lsx_vftint_lu_d(_1); } // CHECK-LABEL: @vftintrz_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrz_w_s(v4f32 _1) { return __builtin_lsx_vftintrz_w_s(_1); } // CHECK-LABEL: @vftintrz_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrz_l_d(v2f64 _1) { return __builtin_lsx_vftintrz_l_d(_1); } // CHECK-LABEL: @vftintrz_wu_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.wu.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.wu.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vftintrz_wu_s(v4f32 _1) { return __builtin_lsx_vftintrz_wu_s(_1); } // CHECK-LABEL: @vftintrz_lu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.lu.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrz.lu.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vftintrz_lu_d(v2f64 _1) { return __builtin_lsx_vftintrz_lu_d(_1); } // CHECK-LABEL: @vffint_s_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vffint_s_w(v4i32 _1) { return __builtin_lsx_vffint_s_w(_1); } // CHECK-LABEL: @vffint_d_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.l(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.l(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffint_d_l(v2i64 _1) { return __builtin_lsx_vffint_d_l(_1); } // CHECK-LABEL: @vffint_s_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.wu(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.wu(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4f32 vffint_s_wu(v4u32 _1) { return __builtin_lsx_vffint_s_wu(_1); } // CHECK-LABEL: @vffint_d_lu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.lu(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffint.d.lu(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffint_d_lu(v2u64 _1) { return __builtin_lsx_vffint_d_lu(_1); } // CHECK-LABEL: @vandn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandn.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vandn.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vandn_v(v16u8 _1, v16u8 _2) { return __builtin_lsx_vandn_v(_1, _2); } // CHECK-LABEL: @vneg_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vneg.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vneg.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vneg_b(v16i8 _1) { return __builtin_lsx_vneg_b(_1); } // CHECK-LABEL: @vneg_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vneg.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vneg.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vneg_h(v8i16 _1) { return __builtin_lsx_vneg_h(_1); } // CHECK-LABEL: @vneg_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vneg.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vneg.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vneg_w(v4i32 _1) { return __builtin_lsx_vneg_w(_1); } // CHECK-LABEL: @vneg_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vneg.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vneg.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vneg_d(v2i64 _1) { return __builtin_lsx_vneg_d(_1); } // CHECK-LABEL: @vmuh_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vmuh_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmuh_b(_1, _2); } // CHECK-LABEL: @vmuh_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmuh_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmuh_h(_1, _2); } // CHECK-LABEL: @vmuh_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmuh_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmuh_w(_1, _2); } // CHECK-LABEL: @vmuh_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmuh_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmuh_d(_1, _2); } // CHECK-LABEL: @vmuh_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmuh.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vmuh_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vmuh_bu(_1, _2); } // CHECK-LABEL: @vmuh_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmuh.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vmuh_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vmuh_hu(_1, _2); } // CHECK-LABEL: @vmuh_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmuh.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vmuh_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vmuh_wu(_1, _2); } // CHECK-LABEL: @vmuh_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmuh.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vmuh_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vmuh_du(_1, _2); } // CHECK-LABEL: @vsllwil_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vsllwil_h_b(v16i8 _1) { return __builtin_lsx_vsllwil_h_b(_1, 1); } // CHECK-LABEL: @vsllwil_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vsllwil_w_h(v8i16 _1) { return __builtin_lsx_vsllwil_w_h(_1, 1); } // CHECK-LABEL: @vsllwil_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vsllwil_d_w(v4i32 _1) { return __builtin_lsx_vsllwil_d_w(_1, 1); } // CHECK-LABEL: @vsllwil_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vsllwil_hu_bu(v16u8 _1) { return __builtin_lsx_vsllwil_hu_bu(_1, 1); } // CHECK-LABEL: @vsllwil_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vsllwil_wu_hu(v8u16 _1) { return __builtin_lsx_vsllwil_wu_hu(_1, 1); } // CHECK-LABEL: @vsllwil_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vsllwil_du_wu(v4u32 _1) { return __builtin_lsx_vsllwil_du_wu(_1, 1); } // CHECK-LABEL: @vsran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsran.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsran.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsran_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsran_b_h(_1, _2); } // CHECK-LABEL: @vsran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsran.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsran.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsran_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsran_h_w(_1, _2); } // CHECK-LABEL: @vsran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsran.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsran.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsran_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsran_w_d(_1, _2); } // CHECK-LABEL: @vssran_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssran_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssran_b_h(_1, _2); } // CHECK-LABEL: @vssran_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssran_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssran_h_w(_1, _2); } // CHECK-LABEL: @vssran_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssran_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssran_w_d(_1, _2); } // CHECK-LABEL: @vssran_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssran.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssran_bu_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vssran_bu_h(_1, _2); } // CHECK-LABEL: @vssran_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssran.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssran_hu_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vssran_hu_w(_1, _2); } // CHECK-LABEL: @vssran_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssran.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssran_wu_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vssran_wu_d(_1, _2); } // CHECK-LABEL: @vsrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrarn_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrarn_b_h(_1, _2); } // CHECK-LABEL: @vsrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrarn_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrarn_h_w(_1, _2); } // CHECK-LABEL: @vsrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrarn_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrarn_w_d(_1, _2); } // CHECK-LABEL: @vssrarn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrarn_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrarn_b_h(_1, _2); } // CHECK-LABEL: @vssrarn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrarn_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrarn_h_w(_1, _2); } // CHECK-LABEL: @vssrarn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrarn_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrarn_w_d(_1, _2); } // CHECK-LABEL: @vssrarn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarn.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrarn_bu_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vssrarn_bu_h(_1, _2); } // CHECK-LABEL: @vssrarn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarn.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrarn_hu_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vssrarn_hu_w(_1, _2); } // CHECK-LABEL: @vssrarn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarn.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrarn_wu_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vssrarn_wu_d(_1, _2); } // CHECK-LABEL: @vsrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrln.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrln.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrln_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrln_b_h(_1, _2); } // CHECK-LABEL: @vsrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrln.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrln.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrln_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrln_h_w(_1, _2); } // CHECK-LABEL: @vsrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrln.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrln.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrln_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrln_w_d(_1, _2); } // CHECK-LABEL: @vssrln_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrln_bu_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vssrln_bu_h(_1, _2); } // CHECK-LABEL: @vssrln_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrln_hu_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vssrln_hu_w(_1, _2); } // CHECK-LABEL: @vssrln_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrln_wu_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vssrln_wu_d(_1, _2); } // CHECK-LABEL: @vsrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlrn_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrlrn_b_h(_1, _2); } // CHECK-LABEL: @vsrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlrn_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrlrn_h_w(_1, _2); } // CHECK-LABEL: @vsrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlrn_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrlrn_w_d(_1, _2); } // CHECK-LABEL: @vssrlrn_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.bu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.bu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrlrn_bu_h(v8u16 _1, v8u16 _2) { return __builtin_lsx_vssrlrn_bu_h(_1, _2); } // CHECK-LABEL: @vssrlrn_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.hu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.hu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrlrn_hu_w(v4u32 _1, v4u32 _2) { return __builtin_lsx_vssrlrn_hu_w(_1, _2); } // CHECK-LABEL: @vssrlrn_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.wu.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.wu.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrlrn_wu_d(v2u64 _1, v2u64 _2) { return __builtin_lsx_vssrlrn_wu_d(_1, _2); } // CHECK-LABEL: @vfrstpi_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vfrstpi_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vfrstpi_b(_1, _2, 1); } // CHECK-LABEL: @vfrstpi_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vfrstpi_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vfrstpi_h(_1, _2, 1); } // CHECK-LABEL: @vfrstp_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstp.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vfrstp.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vfrstp_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __builtin_lsx_vfrstp_b(_1, _2, _3); } // CHECK-LABEL: @vfrstp_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstp.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vfrstp.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vfrstp_h(v8i16 _1, v8i16 _2, v8i16 _3) { return __builtin_lsx_vfrstp_h(_1, _2, _3); } // CHECK-LABEL: @vshuf4i_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vshuf4i_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vshuf4i_d(_1, _2, 1); } // CHECK-LABEL: @vbsrl_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vbsrl_v(v16i8 _1) { return __builtin_lsx_vbsrl_v(_1, 1); } // CHECK-LABEL: @vbsll_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vbsll_v(v16i8 _1) { return __builtin_lsx_vbsll_v(_1, 1); } // CHECK-LABEL: @vextrins_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vextrins_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vextrins_b(_1, _2, 1); } // CHECK-LABEL: @vextrins_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vextrins_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vextrins_h(_1, _2, 1); } // CHECK-LABEL: @vextrins_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vextrins_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vextrins_w(_1, _2, 1); } // CHECK-LABEL: @vextrins_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vextrins_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vextrins_d(_1, _2, 1); } // CHECK-LABEL: @vmskltz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskltz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskltz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmskltz_b(v16i8 _1) { return __builtin_lsx_vmskltz_b(_1); } // CHECK-LABEL: @vmskltz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmskltz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmskltz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vmskltz_h(v8i16 _1) { return __builtin_lsx_vmskltz_h(_1); } // CHECK-LABEL: @vmskltz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmskltz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmskltz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vmskltz_w(v4i32 _1) { return __builtin_lsx_vmskltz_w(_1); } // CHECK-LABEL: @vmskltz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmskltz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmskltz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vmskltz_d(v2i64 _1) { return __builtin_lsx_vmskltz_d(_1); } // CHECK-LABEL: @vsigncov_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsigncov.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsigncov.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsigncov_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsigncov_b(_1, _2); } // CHECK-LABEL: @vsigncov_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsigncov.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsigncov.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsigncov_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsigncov_h(_1, _2); } // CHECK-LABEL: @vsigncov_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsigncov.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsigncov.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsigncov_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsigncov_w(_1, _2); } // CHECK-LABEL: @vsigncov_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsigncov.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsigncov.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsigncov_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsigncov_d(_1, _2); } // CHECK-LABEL: @vfmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmadd.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmadd.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfmadd_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __builtin_lsx_vfmadd_s(_1, _2, _3); } // CHECK-LABEL: @vfmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmadd.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmadd.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfmadd_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __builtin_lsx_vfmadd_d(_1, _2, _3); } // CHECK-LABEL: @vfmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmsub.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfmsub.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfmsub_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __builtin_lsx_vfmsub_s(_1, _2, _3); } // CHECK-LABEL: @vfmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmsub.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfmsub.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfmsub_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __builtin_lsx_vfmsub_d(_1, _2, _3); } // CHECK-LABEL: @vfnmadd_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmadd.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmadd.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfnmadd_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __builtin_lsx_vfnmadd_s(_1, _2, _3); } // CHECK-LABEL: @vfnmadd_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmadd.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmadd.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfnmadd_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __builtin_lsx_vfnmadd_d(_1, _2, _3); } // CHECK-LABEL: @vfnmsub_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmsub.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]], <4 x float> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfnmsub.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]], <4 x float> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4f32 vfnmsub_s(v4f32 _1, v4f32 _2, v4f32 _3) { return __builtin_lsx_vfnmsub_s(_1, _2, _3); } // CHECK-LABEL: @vfnmsub_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmsub.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]], <2 x double> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfnmsub.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2f64 vfnmsub_d(v2f64 _1, v2f64 _2, v2f64 _3) { return __builtin_lsx_vfnmsub_d(_1, _2, _3); } // CHECK-LABEL: @vftintrne_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrne_w_s(v4f32 _1) { return __builtin_lsx_vftintrne_w_s(_1); } // CHECK-LABEL: @vftintrne_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrne.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrne.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrne_l_d(v2f64 _1) { return __builtin_lsx_vftintrne_l_d(_1); } // CHECK-LABEL: @vftintrp_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrp_w_s(v4f32 _1) { return __builtin_lsx_vftintrp_w_s(_1); } // CHECK-LABEL: @vftintrp_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrp.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrp.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrp_l_d(v2f64 _1) { return __builtin_lsx_vftintrp_l_d(_1); } // CHECK-LABEL: @vftintrm_w_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vftintrm_w_s(v4f32 _1) { return __builtin_lsx_vftintrm_w_s(_1); } // CHECK-LABEL: @vftintrm_l_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrm.l.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrm.l.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrm_l_d(v2f64 _1) { return __builtin_lsx_vftintrm_l_d(_1); } // CHECK-LABEL: @vftint_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftint.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftint_w_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vftint_w_d(_1, _2); } // CHECK-LABEL: @vffint_s_l( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.l(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x float> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vffint.s.l(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x float> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4f32 vffint_s_l(v2i64 _1, v2i64 _2) { return __builtin_lsx_vffint_s_l(_1, _2); } // CHECK-LABEL: @vftintrz_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrz_w_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vftintrz_w_d(_1, _2); } // CHECK-LABEL: @vftintrp_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrp_w_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vftintrp_w_d(_1, _2); } // CHECK-LABEL: @vftintrm_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrm_w_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vftintrm_w_d(_1, _2); } // CHECK-LABEL: @vftintrne_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vftintrne_w_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vftintrne_w_d(_1, _2); } // CHECK-LABEL: @vftintl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintl.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintl.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintl_l_s(v4f32 _1) { return __builtin_lsx_vftintl_l_s(_1); } // CHECK-LABEL: @vftinth_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftinth.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftinth.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftinth_l_s(v4f32 _1) { return __builtin_lsx_vftinth_l_s(_1); } // CHECK-LABEL: @vffinth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffinth.d.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffinth.d.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffinth_d_w(v4i32 _1) { return __builtin_lsx_vffinth_d_w(_1); } // CHECK-LABEL: @vffintl_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffintl.d.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x double> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vffintl.d.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2f64 vffintl_d_w(v4i32 _1) { return __builtin_lsx_vffintl_d_w(_1); } // CHECK-LABEL: @vftintrzl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzl.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzl.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrzl_l_s(v4f32 _1) { return __builtin_lsx_vftintrzl_l_s(_1); } // CHECK-LABEL: @vftintrzh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzh.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrzh.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrzh_l_s(v4f32 _1) { return __builtin_lsx_vftintrzh_l_s(_1); } // CHECK-LABEL: @vftintrpl_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrpl.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrpl.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrpl_l_s(v4f32 _1) { return __builtin_lsx_vftintrpl_l_s(_1); } // CHECK-LABEL: @vftintrph_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrph.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrph.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrph_l_s(v4f32 _1) { return __builtin_lsx_vftintrph_l_s(_1); } // CHECK-LABEL: @vftintrml_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrml.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrml.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrml_l_s(v4f32 _1) { return __builtin_lsx_vftintrml_l_s(_1); } // CHECK-LABEL: @vftintrmh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrmh.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrmh.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrmh_l_s(v4f32 _1) { return __builtin_lsx_vftintrmh_l_s(_1); } // CHECK-LABEL: @vftintrnel_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrnel.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrnel.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrnel_l_s(v4f32 _1) { return __builtin_lsx_vftintrnel_l_s(_1); } // CHECK-LABEL: @vftintrneh_l_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrneh.l.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vftintrneh.l.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vftintrneh_l_s(v4f32 _1) { return __builtin_lsx_vftintrneh_l_s(_1); } // CHECK-LABEL: @vfrintrne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrne.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrne.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrne_s(v4f32 _1) { return __builtin_lsx_vfrintrne_s(_1); } // CHECK-LABEL: @vfrintrne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrne.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrne.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrne_d(v2f64 _1) { return __builtin_lsx_vfrintrne_d(_1); } // CHECK-LABEL: @vfrintrz_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrz.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrz.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrz_s(v4f32 _1) { return __builtin_lsx_vfrintrz_s(_1); } // CHECK-LABEL: @vfrintrz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrz.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrz.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrz_d(v2f64 _1) { return __builtin_lsx_vfrintrz_d(_1); } // CHECK-LABEL: @vfrintrp_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrp.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrp.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrp_s(v4f32 _1) { return __builtin_lsx_vfrintrp_s(_1); } // CHECK-LABEL: @vfrintrp_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrp.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrp.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrp_d(v2f64 _1) { return __builtin_lsx_vfrintrp_d(_1); } // CHECK-LABEL: @vfrintrm_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrm.s(<4 x float> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <4 x i32> -// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.loongarch.lsx.vfrintrm.s(<4 x float> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vfrintrm_s(v4f32 _1) { return __builtin_lsx_vfrintrm_s(_1); } // CHECK-LABEL: @vfrintrm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrm.d(<2 x double> [[_1:%.*]]) -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[TMP0]] to <2 x i64> -// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.loongarch.lsx.vfrintrm.d(<2 x double> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x double> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vfrintrm_d(v2f64 _1) { return __builtin_lsx_vfrintrm_d(_1); } // CHECK-LABEL: @vstelm_b( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> [[TMP0]], ptr [[_2:%.*]], i32 1, i32 1) // CHECK-NEXT: ret void // void vstelm_b(v16i8 _1, void *_2) { @@ -3349,7 +4577,8 @@ void vstelm_b(v16i8 _1, void *_2) { } // CHECK-LABEL: @vstelm_h( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> [[_1:%.*]], ptr [[_2:%.*]], i32 2, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> [[TMP0]], ptr [[_2:%.*]], i32 2, i32 1) // CHECK-NEXT: ret void // void vstelm_h(v8i16 _1, void *_2) { @@ -3357,7 +4586,8 @@ void vstelm_h(v8i16 _1, void *_2) { } // CHECK-LABEL: @vstelm_w( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> [[_1:%.*]], ptr [[_2:%.*]], i32 4, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> [[TMP0]], ptr [[_2:%.*]], i32 4, i32 1) // CHECK-NEXT: ret void // void vstelm_w(v4i32 _1, void *_2) { @@ -3365,7 +4595,8 @@ void vstelm_w(v4i32 _1, void *_2) { } // CHECK-LABEL: @vstelm_d( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> [[_1:%.*]], ptr [[_2:%.*]], i32 8, i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> [[TMP0]], ptr [[_2:%.*]], i32 8, i32 1) // CHECK-NEXT: ret void // void vstelm_d(v2i64 _1, void *_2) { @@ -3373,1286 +4604,1785 @@ void vstelm_d(v2i64 _1, void *_2) { } // CHECK-LABEL: @vaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vaddwev_d_w(_1, _2); } // CHECK-LABEL: @vaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwev_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vaddwev_w_h(_1, _2); } // CHECK-LABEL: @vaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwev_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vaddwev_h_b(_1, _2); } // CHECK-LABEL: @vaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vaddwod_d_w(_1, _2); } // CHECK-LABEL: @vaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwod_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vaddwod_w_h(_1, _2); } // CHECK-LABEL: @vaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwod_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vaddwod_h_b(_1, _2); } // CHECK-LABEL: @vaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_d_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vaddwev_d_wu(_1, _2); } // CHECK-LABEL: @vaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwev_w_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vaddwev_w_hu(_1, _2); } // CHECK-LABEL: @vaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwev_h_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vaddwev_h_bu(_1, _2); } // CHECK-LABEL: @vaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_d_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vaddwod_d_wu(_1, _2); } // CHECK-LABEL: @vaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwod_w_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vaddwod_w_hu(_1, _2); } // CHECK-LABEL: @vaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwod_h_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vaddwod_h_bu(_1, _2); } // CHECK-LABEL: @vaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_d_wu_w(v4u32 _1, v4i32 _2) { return __builtin_lsx_vaddwev_d_wu_w(_1, _2); } // CHECK-LABEL: @vaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwev_w_hu_h(v8u16 _1, v8i16 _2) { return __builtin_lsx_vaddwev_w_hu_h(_1, _2); } // CHECK-LABEL: @vaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwev_h_bu_b(v16u8 _1, v16i8 _2) { return __builtin_lsx_vaddwev_h_bu_b(_1, _2); } // CHECK-LABEL: @vaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_d_wu_w(v4u32 _1, v4i32 _2) { return __builtin_lsx_vaddwod_d_wu_w(_1, _2); } // CHECK-LABEL: @vaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vaddwod_w_hu_h(v8u16 _1, v8i16 _2) { return __builtin_lsx_vaddwod_w_hu_h(_1, _2); } // CHECK-LABEL: @vaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vaddwod_h_bu_b(v16u8 _1, v16i8 _2) { return __builtin_lsx_vaddwod_h_bu_b(_1, _2); } // CHECK-LABEL: @vsubwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsubwev_d_w(_1, _2); } // CHECK-LABEL: @vsubwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwev_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsubwev_w_h(_1, _2); } // CHECK-LABEL: @vsubwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwev_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsubwev_h_b(_1, _2); } // CHECK-LABEL: @vsubwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsubwod_d_w(_1, _2); } // CHECK-LABEL: @vsubwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwod_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsubwod_w_h(_1, _2); } // CHECK-LABEL: @vsubwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwod_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsubwod_h_b(_1, _2); } // CHECK-LABEL: @vsubwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_d_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vsubwev_d_wu(_1, _2); } // CHECK-LABEL: @vsubwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwev_w_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vsubwev_w_hu(_1, _2); } // CHECK-LABEL: @vsubwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwev_h_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vsubwev_h_bu(_1, _2); } // CHECK-LABEL: @vsubwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_d_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vsubwod_d_wu(_1, _2); } // CHECK-LABEL: @vsubwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsubwod_w_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vsubwod_w_hu(_1, _2); } // CHECK-LABEL: @vsubwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsubwod_h_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vsubwod_h_bu(_1, _2); } // CHECK-LABEL: @vaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vaddwev_q_d(_1, _2); } // CHECK-LABEL: @vaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vaddwod_q_d(_1, _2); } // CHECK-LABEL: @vaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_q_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vaddwev_q_du(_1, _2); } // CHECK-LABEL: @vaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_q_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vaddwod_q_du(_1, _2); } // CHECK-LABEL: @vsubwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsubwev_q_d(_1, _2); } // CHECK-LABEL: @vsubwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsubwod_q_d(_1, _2); } // CHECK-LABEL: @vsubwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwev_q_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vsubwev_q_du(_1, _2); } // CHECK-LABEL: @vsubwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsubwod_q_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vsubwod_q_du(_1, _2); } // CHECK-LABEL: @vaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwev_q_du_d(v2u64 _1, v2i64 _2) { return __builtin_lsx_vaddwev_q_du_d(_1, _2); } // CHECK-LABEL: @vaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vaddwod_q_du_d(v2u64 _1, v2i64 _2) { return __builtin_lsx_vaddwod_q_du_d(_1, _2); } // CHECK-LABEL: @vmulwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmulwev_d_w(_1, _2); } // CHECK-LABEL: @vmulwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwev_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmulwev_w_h(_1, _2); } // CHECK-LABEL: @vmulwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwev_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmulwev_h_b(_1, _2); } // CHECK-LABEL: @vmulwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_d_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vmulwod_d_w(_1, _2); } // CHECK-LABEL: @vmulwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwod_w_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vmulwod_w_h(_1, _2); } // CHECK-LABEL: @vmulwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwod_h_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vmulwod_h_b(_1, _2); } // CHECK-LABEL: @vmulwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_d_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vmulwev_d_wu(_1, _2); } // CHECK-LABEL: @vmulwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwev_w_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vmulwev_w_hu(_1, _2); } // CHECK-LABEL: @vmulwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwev_h_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vmulwev_h_bu(_1, _2); } // CHECK-LABEL: @vmulwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_d_wu(v4u32 _1, v4u32 _2) { return __builtin_lsx_vmulwod_d_wu(_1, _2); } // CHECK-LABEL: @vmulwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwod_w_hu(v8u16 _1, v8u16 _2) { return __builtin_lsx_vmulwod_w_hu(_1, _2); } // CHECK-LABEL: @vmulwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwod_h_bu(v16u8 _1, v16u8 _2) { return __builtin_lsx_vmulwod_h_bu(_1, _2); } // CHECK-LABEL: @vmulwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_d_wu_w(v4u32 _1, v4i32 _2) { return __builtin_lsx_vmulwev_d_wu_w(_1, _2); } // CHECK-LABEL: @vmulwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwev_w_hu_h(v8u16 _1, v8i16 _2) { return __builtin_lsx_vmulwev_w_hu_h(_1, _2); } // CHECK-LABEL: @vmulwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwev_h_bu_b(v16u8 _1, v16i8 _2) { return __builtin_lsx_vmulwev_h_bu_b(_1, _2); } // CHECK-LABEL: @vmulwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_d_wu_w(v4u32 _1, v4i32 _2) { return __builtin_lsx_vmulwod_d_wu_w(_1, _2); } // CHECK-LABEL: @vmulwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vmulwod_w_hu_h(v8u16 _1, v8i16 _2) { return __builtin_lsx_vmulwod_w_hu_h(_1, _2); } // CHECK-LABEL: @vmulwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vmulwod_h_bu_b(v16u8 _1, v16i8 _2) { return __builtin_lsx_vmulwod_h_bu_b(_1, _2); } // CHECK-LABEL: @vmulwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmulwev_q_d(_1, _2); } // CHECK-LABEL: @vmulwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vmulwod_q_d(_1, _2); } // CHECK-LABEL: @vmulwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_q_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vmulwev_q_du(_1, _2); } // CHECK-LABEL: @vmulwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_q_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vmulwod_q_du(_1, _2); } // CHECK-LABEL: @vmulwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwev_q_du_d(v2u64 _1, v2i64 _2) { return __builtin_lsx_vmulwev_q_du_d(_1, _2); } // CHECK-LABEL: @vmulwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vmulwod_q_du_d(v2u64 _1, v2i64 _2) { return __builtin_lsx_vmulwod_q_du_d(_1, _2); } // CHECK-LABEL: @vhaddw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhaddw_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vhaddw_q_d(_1, _2); } // CHECK-LABEL: @vhaddw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.qu.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhaddw.qu.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vhaddw_qu_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vhaddw_qu_du(_1, _2); } // CHECK-LABEL: @vhsubw_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vhsubw_q_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vhsubw_q_d(_1, _2); } // CHECK-LABEL: @vhsubw_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.qu.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vhsubw.qu.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vhsubw_qu_du(v2u64 _1, v2u64 _2) { return __builtin_lsx_vhsubw_qu_du(_1, _2); } // CHECK-LABEL: @vmaddwev_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_d_w(v2i64 _1, v4i32 _2, v4i32 _3) { return __builtin_lsx_vmaddwev_d_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwev_w_h(v4i32 _1, v8i16 _2, v8i16 _3) { return __builtin_lsx_vmaddwev_w_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwev_h_b(v8i16 _1, v16i8 _2, v16i8 _3) { return __builtin_lsx_vmaddwev_h_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwev_d_wu(v2u64 _1, v4u32 _2, v4u32 _3) { return __builtin_lsx_vmaddwev_d_wu(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4u32 vmaddwev_w_hu(v4u32 _1, v8u16 _2, v8u16 _3) { return __builtin_lsx_vmaddwev_w_hu(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8u16 vmaddwev_h_bu(v8u16 _1, v16u8 _2, v16u8 _3) { return __builtin_lsx_vmaddwev_h_bu(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_d_w(v2i64 _1, v4i32 _2, v4i32 _3) { return __builtin_lsx_vmaddwod_d_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwod_w_h(v4i32 _1, v8i16 _2, v8i16 _3) { return __builtin_lsx_vmaddwod_w_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwod_h_b(v8i16 _1, v16i8 _2, v16i8 _3) { return __builtin_lsx_vmaddwod_h_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_d_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwod_d_wu(v2u64 _1, v4u32 _2, v4u32 _3) { return __builtin_lsx_vmaddwod_d_wu(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_w_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4u32 vmaddwod_w_hu(v4u32 _1, v8u16 _2, v8u16 _3) { return __builtin_lsx_vmaddwod_w_hu(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_h_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8u16 vmaddwod_h_bu(v8u16 _1, v16u8 _2, v16u8 _3) { return __builtin_lsx_vmaddwod_h_bu(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_d_wu_w(v2i64 _1, v4u32 _2, v4i32 _3) { return __builtin_lsx_vmaddwev_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwev_w_hu_h(v4i32 _1, v8u16 _2, v8i16 _3) { return __builtin_lsx_vmaddwev_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwev_h_bu_b(v8i16 _1, v16u8 _2, v16i8 _3) { return __builtin_lsx_vmaddwev_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_d_wu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu.w(<2 x i64> [[_1:%.*]], <4 x i32> [[_2:%.*]], <4 x i32> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu.w(<2 x i64> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_d_wu_w(v2i64 _1, v4u32 _2, v4i32 _3) { return __builtin_lsx_vmaddwod_d_wu_w(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_w_hu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu.h(<4 x i32> [[_1:%.*]], <8 x i16> [[_2:%.*]], <8 x i16> [[_3:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu.h(<4 x i32> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v4i32 vmaddwod_w_hu_h(v4i32 _1, v8u16 _2, v8i16 _3) { return __builtin_lsx_vmaddwod_w_hu_h(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_h_bu_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu.b(<8 x i16> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu.b(<8 x i16> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v8i16 vmaddwod_h_bu_b(v8i16 _1, v16u8 _2, v16i8 _3) { return __builtin_lsx_vmaddwod_h_bu_b(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_q_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __builtin_lsx_vmaddwev_q_d(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_q_d(v2i64 _1, v2i64 _2, v2i64 _3) { return __builtin_lsx_vmaddwod_q_d(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwev_q_du(v2u64 _1, v2u64 _2, v2u64 _3) { return __builtin_lsx_vmaddwev_q_du(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_q_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2u64 vmaddwod_q_du(v2u64 _1, v2u64 _2, v2u64 _3) { return __builtin_lsx_vmaddwod_q_du(_1, _2, _3); } // CHECK-LABEL: @vmaddwev_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwev_q_du_d(v2i64 _1, v2u64 _2, v2i64 _3) { return __builtin_lsx_vmaddwev_q_du_d(_1, _2, _3); } // CHECK-LABEL: @vmaddwod_q_du_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], <2 x i64> [[_3:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], <2 x i64> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v2i64 vmaddwod_q_du_d(v2i64 _1, v2u64 _2, v2i64 _3) { return __builtin_lsx_vmaddwod_q_du_d(_1, _2, _3); } // CHECK-LABEL: @vrotr_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotr.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotr.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vrotr_b(v16i8 _1, v16i8 _2) { return __builtin_lsx_vrotr_b(_1, _2); } // CHECK-LABEL: @vrotr_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotr.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotr.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vrotr_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vrotr_h(_1, _2); } // CHECK-LABEL: @vrotr_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotr.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotr.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vrotr_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vrotr_w(_1, _2); } // CHECK-LABEL: @vrotr_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotr.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotr.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vrotr_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vrotr_d(_1, _2); } // CHECK-LABEL: @vadd_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vadd.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vadd_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vadd_q(_1, _2); } // CHECK-LABEL: @vsub_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsub.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsub_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsub_q(_1, _2); } // CHECK-LABEL: @vldrepl_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vldrepl.b(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vldrepl_b(void *_1) { return __builtin_lsx_vldrepl_b(_1, 1); } // CHECK-LABEL: @vldrepl_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vldrepl.h(ptr [[_1:%.*]], i32 2) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v8i16 vldrepl_h(void *_1) { return __builtin_lsx_vldrepl_h(_1, 2); } // CHECK-LABEL: @vldrepl_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(ptr [[_1:%.*]], i32 4) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v4i32 vldrepl_w(void *_1) { return __builtin_lsx_vldrepl_w(_1, 4); } // CHECK-LABEL: @vldrepl_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vldrepl.d(ptr [[_1:%.*]], i32 8) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vldrepl_d(void *_1) { return __builtin_lsx_vldrepl_d(_1, 8); } // CHECK-LABEL: @vmskgez_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskgez.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmskgez.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmskgez_b(v16i8 _1) { return __builtin_lsx_vmskgez_b(_1); } // CHECK-LABEL: @vmsknz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsknz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vmsknz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vmsknz_b(v16i8 _1) { return __builtin_lsx_vmsknz_b(_1); } // CHECK-LABEL: @vexth_h_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.h.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.h.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vexth_h_b(v16i8 _1) { return __builtin_lsx_vexth_h_b(_1); } // CHECK-LABEL: @vexth_w_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.w.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.w.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vexth_w_h(v8i16 _1) { return __builtin_lsx_vexth_w_h(_1); } // CHECK-LABEL: @vexth_d_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.d.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.d.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vexth_d_w(v4i32 _1) { return __builtin_lsx_vexth_d_w(_1); } // CHECK-LABEL: @vexth_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.q.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.q.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vexth_q_d(v2i64 _1) { return __builtin_lsx_vexth_q_d(_1); } // CHECK-LABEL: @vexth_hu_bu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.hu.bu(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vexth.hu.bu(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8u16 vexth_hu_bu(v16u8 _1) { return __builtin_lsx_vexth_hu_bu(_1); } // CHECK-LABEL: @vexth_wu_hu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.wu.hu(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vexth.wu.hu(<8 x i16> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4u32 vexth_wu_hu(v8u16 _1) { return __builtin_lsx_vexth_wu_hu(_1); } // CHECK-LABEL: @vexth_du_wu( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.du.wu(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.du.wu(<4 x i32> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vexth_du_wu(v4u32 _1) { return __builtin_lsx_vexth_du_wu(_1); } // CHECK-LABEL: @vexth_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.qu.du(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vexth.qu.du(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vexth_qu_du(v2u64 _1) { return __builtin_lsx_vexth_qu_du(_1); } // CHECK-LABEL: @vrotri_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v16i8 vrotri_b(v16i8 _1) { return __builtin_lsx_vrotri_b(_1, 1); } // CHECK-LABEL: @vrotri_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v8i16 vrotri_h(v8i16 _1) { return __builtin_lsx_vrotri_h(_1, 1); } // CHECK-LABEL: @vrotri_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v4i32 vrotri_w(v4i32 _1) { return __builtin_lsx_vrotri_w(_1, 1); } // CHECK-LABEL: @vrotri_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> [[TMP0]], i32 1) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vrotri_d(v2i64 _1) { return __builtin_lsx_vrotri_d(_1, 1); } // CHECK-LABEL: @vextl_q_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.q.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.q.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2i64 vextl_q_d(v2i64 _1) { return __builtin_lsx_vextl_q_d(_1); } // CHECK-LABEL: @vsrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlni_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlni_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlni_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrlni_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrlrni_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrlrni_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrlrni_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrlrni_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrlni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrlni_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vssrlni_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrlni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrlni_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrlni_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrlni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrlni_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrlni_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrlni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrlni_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrlni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrlni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrlni_bu_h(v16u8 _1, v16i8 _2) { return __builtin_lsx_vssrlni_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrlni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrlni_hu_w(v8u16 _1, v8i16 _2) { return __builtin_lsx_vssrlni_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrlni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrlni_wu_d(v4u32 _1, v4i32 _2) { return __builtin_lsx_vssrlni_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrlni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrlni_du_q(v2u64 _1, v2i64 _2) { return __builtin_lsx_vssrlni_du_q(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrlrni_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vssrlrni_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrlrni_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrlrni_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrlrni_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrlrni_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrlrni_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrlrni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrlrni_bu_h(v16u8 _1, v16i8 _2) { return __builtin_lsx_vssrlrni_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrlrni_hu_w(v8u16 _1, v8i16 _2) { return __builtin_lsx_vssrlrni_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrlrni_wu_d(v4u32 _1, v4i32 _2) { return __builtin_lsx_vssrlrni_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrlrni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrlrni_du_q(v2u64 _1, v2i64 _2) { return __builtin_lsx_vssrlrni_du_q(_1, _2, 1); } // CHECK-LABEL: @vsrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrani_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrani_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrani_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrani_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrani_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrani_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrani_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrani_d_q(_1, _2, 1); } // CHECK-LABEL: @vsrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vsrarni_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vsrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @vsrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vsrarni_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vsrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @vsrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vsrarni_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vsrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @vsrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vsrarni_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vsrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrani_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrani_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vssrani_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrani_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrani_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrani_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrani_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrani_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrani_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrani_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrani_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrani_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrani_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrani_bu_h(v16u8 _1, v16i8 _2) { return __builtin_lsx_vssrani_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrani_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrani_hu_w(v8u16 _1, v8i16 _2) { return __builtin_lsx_vssrani_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrani_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrani_wu_d(v4u32 _1, v4i32 _2) { return __builtin_lsx_vssrani_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrani_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrani_du_q(v2u64 _1, v2i64 _2) { return __builtin_lsx_vssrani_du_q(_1, _2, 1); } // CHECK-LABEL: @vssrarni_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrarni_b_h(v16i8 _1, v16i8 _2) { return __builtin_lsx_vssrarni_b_h(_1, _2, 1); } // CHECK-LABEL: @vssrarni_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrarni_h_w(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrarni_h_w(_1, _2, 1); } // CHECK-LABEL: @vssrarni_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrarni_w_d(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrarni_w_d(_1, _2, 1); } // CHECK-LABEL: @vssrarni_d_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vssrarni_d_q(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrarni_d_q(_1, _2, 1); } // CHECK-LABEL: @vssrarni_bu_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16u8 vssrarni_bu_h(v16u8 _1, v16i8 _2) { return __builtin_lsx_vssrarni_bu_h(_1, _2, 1); } // CHECK-LABEL: @vssrarni_hu_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8u16 vssrarni_hu_w(v8u16 _1, v8i16 _2) { return __builtin_lsx_vssrarni_hu_w(_1, _2, 1); } // CHECK-LABEL: @vssrarni_wu_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4u32 vssrarni_wu_d(v4u32 _1, v4i32 _2) { return __builtin_lsx_vssrarni_wu_d(_1, _2, 1); } // CHECK-LABEL: @vssrarni_du_q( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2u64 vssrarni_du_q(v2u64 _1, v2i64 _2) { return __builtin_lsx_vssrarni_du_q(_1, _2, 1); } // CHECK-LABEL: @vpermi_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]], i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]], i32 1) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vpermi_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vpermi_w(_1, _2, 1); @@ -4660,79 +6390,107 @@ v4i32 vpermi_w(v4i32 _1, v4i32 _2) { // CHECK-LABEL: @vld( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vld(ptr [[_1:%.*]], i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vld(void *_1) { return __builtin_lsx_vld(_1, 1); } // CHECK-LABEL: @vst( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vst(<16 x i8> [[_1:%.*]], ptr [[_2:%.*]], i32 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vst(<16 x i8> [[TMP0]], ptr [[_2:%.*]], i32 1) // CHECK-NEXT: ret void // void vst(v16i8 _1, void *_2) { return __builtin_lsx_vst(_1, _2, 1); } // CHECK-LABEL: @vssrlrn_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrlrn.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrlrn_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrlrn_b_h(_1, _2); } // CHECK-LABEL: @vssrlrn_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrlrn.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrlrn_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrlrn_h_w(_1, _2); } // CHECK-LABEL: @vssrlrn_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrlrn.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrlrn_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrlrn_w_d(_1, _2); } // CHECK-LABEL: @vssrln_b_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.b.h(<8 x i16> [[_1:%.*]], <8 x i16> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vssrln.b.h(<8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vssrln_b_h(v8i16 _1, v8i16 _2) { return __builtin_lsx_vssrln_b_h(_1, _2); } // CHECK-LABEL: @vssrln_h_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.h.w(<4 x i32> [[_1:%.*]], <4 x i32> [[_2:%.*]]) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vssrln.h.w(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v8i16 vssrln_h_w(v4i32 _1, v4i32 _2) { return __builtin_lsx_vssrln_h_w(_1, _2); } // CHECK-LABEL: @vssrln_w_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.w.d(<2 x i64> [[_1:%.*]], <2 x i64> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vssrln.w.d(<2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vssrln_w_d(v2i64 _1, v2i64 _2) { return __builtin_lsx_vssrln_w_d(_1, _2); } // CHECK-LABEL: @vorn_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vorn.v(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vorn.v(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v16i8 vorn_v(v16i8 _1, v16i8 _2) { return __builtin_lsx_vorn_v(_1, _2); } // CHECK-LABEL: @vldi( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vldi(i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vldi() { return __builtin_lsx_vldi(1); } // CHECK-LABEL: @vshuf_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf.b(<16 x i8> [[_1:%.*]], <16 x i8> [[_2:%.*]], <16 x i8> [[_3:%.*]]) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i128 [[_3_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP3:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vshuf.b(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to i128 +// CHECK-NEXT: ret i128 [[TMP4]] // v16i8 vshuf_b(v16i8 _1, v16i8 _2, v16i8 _3) { return __builtin_lsx_vshuf_b(_1, _2, _3); @@ -4740,429 +6498,575 @@ v16i8 vshuf_b(v16i8 _1, v16i8 _2, v16i8 _3) { // CHECK-LABEL: @vldx( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vldx(ptr [[_1:%.*]], i64 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vldx(void *_1) { return __builtin_lsx_vldx(_1, 1); } // CHECK-LABEL: @vstx( // CHECK-NEXT: entry: -// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstx(<16 x i8> [[_1:%.*]], ptr [[_2:%.*]], i64 1) +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: tail call void @llvm.loongarch.lsx.vstx(<16 x i8> [[TMP0]], ptr [[_2:%.*]], i64 1) // CHECK-NEXT: ret void // void vstx(v16i8 _1, void *_2) { return __builtin_lsx_vstx(_1, _2, 1); } // CHECK-LABEL: @vextl_qu_du( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.qu.du(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vextl.qu.du(<2 x i64> [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +// CHECK-NEXT: ret i128 [[TMP2]] // v2u64 vextl_qu_du(v2u64 _1) { return __builtin_lsx_vextl_qu_du(_1); } // CHECK-LABEL: @bnz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_b(v16u8 _1) { return __builtin_lsx_bnz_b(_1); } // CHECK-LABEL: @bnz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_d(v2u64 _1) { return __builtin_lsx_bnz_d(_1); } // CHECK-LABEL: @bnz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_h(v8u16 _1) { return __builtin_lsx_bnz_h(_1); } // CHECK-LABEL: @bnz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.v(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.v(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_v(v16u8 _1) { return __builtin_lsx_bnz_v(_1); } // CHECK-LABEL: @bnz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bnz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bnz_w(v4u32 _1) { return __builtin_lsx_bnz_w(_1); } // CHECK-LABEL: @bz_b( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.b(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.b(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_b(v16u8 _1) { return __builtin_lsx_bz_b(_1); } // CHECK-LABEL: @bz_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.d(<2 x i64> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x i64> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.d(<2 x i64> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_d(v2u64 _1) { return __builtin_lsx_bz_d(_1); } // CHECK-LABEL: @bz_h( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.h(<8 x i16> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <8 x i16> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.h(<8 x i16> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_h(v8u16 _1) { return __builtin_lsx_bz_h(_1); } // CHECK-LABEL: @bz_v( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.v(<16 x i8> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.v(<16 x i8> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_v(v16u8 _1) { return __builtin_lsx_bz_v(_1); } // CHECK-LABEL: @bz_w( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.w(<4 x i32> [[_1:%.*]]) -// CHECK-NEXT: ret i32 [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.lsx.bz.w(<4 x i32> [[TMP0]]) +// CHECK-NEXT: ret i32 [[TMP1]] // int bz_w(v4u32 _1) { return __builtin_lsx_bz_w(_1); } // CHECK-LABEL: @vfcmp_caf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.caf.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.caf.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_caf_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_caf_d(_1, _2); } // CHECK-LABEL: @vfcmp_caf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.caf.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.caf.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_caf_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_caf_s(_1, _2); } // CHECK-LABEL: @vfcmp_ceq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.ceq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.ceq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_ceq_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_ceq_d(_1, _2); } // CHECK-LABEL: @vfcmp_ceq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.ceq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.ceq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_ceq_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_ceq_s(_1, _2); } // CHECK-LABEL: @vfcmp_cle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cle.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cle.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cle_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cle_d(_1, _2); } // CHECK-LABEL: @vfcmp_cle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cle.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cle.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cle_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cle_s(_1, _2); } // CHECK-LABEL: @vfcmp_clt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.clt.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.clt.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_clt_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_clt_d(_1, _2); } // CHECK-LABEL: @vfcmp_clt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.clt.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.clt.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_clt_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_clt_s(_1, _2); } // CHECK-LABEL: @vfcmp_cne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cne.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cne.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cne_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cne_d(_1, _2); } // CHECK-LABEL: @vfcmp_cne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cne.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cne.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cne_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cne_s(_1, _2); } // CHECK-LABEL: @vfcmp_cor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cor.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cor.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cor_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cor_d(_1, _2); } // CHECK-LABEL: @vfcmp_cor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cor.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cor.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cor_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cor_s(_1, _2); } // CHECK-LABEL: @vfcmp_cueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cueq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cueq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cueq_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cueq_d(_1, _2); } // CHECK-LABEL: @vfcmp_cueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cueq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cueq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cueq_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cueq_s(_1, _2); } // CHECK-LABEL: @vfcmp_cule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cule.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cule.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cule_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cule_d(_1, _2); } // CHECK-LABEL: @vfcmp_cule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cule.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cule.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cule_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cule_s(_1, _2); } // CHECK-LABEL: @vfcmp_cult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cult.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cult.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cult_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cult_d(_1, _2); } // CHECK-LABEL: @vfcmp_cult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cult.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cult.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cult_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cult_s(_1, _2); } // CHECK-LABEL: @vfcmp_cun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cun.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cun.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cun_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cun_d(_1, _2); } // CHECK-LABEL: @vfcmp_cune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cune.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.cune.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_cune_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_cune_d(_1, _2); } // CHECK-LABEL: @vfcmp_cune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cune.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cune.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cune_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cune_s(_1, _2); } // CHECK-LABEL: @vfcmp_cun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cun.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.cun.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_cun_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_cun_s(_1, _2); } // CHECK-LABEL: @vfcmp_saf_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.saf.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.saf.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_saf_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_saf_d(_1, _2); } // CHECK-LABEL: @vfcmp_saf_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.saf.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.saf.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_saf_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_saf_s(_1, _2); } // CHECK-LABEL: @vfcmp_seq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.seq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.seq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_seq_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_seq_d(_1, _2); } // CHECK-LABEL: @vfcmp_seq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.seq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.seq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_seq_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_seq_s(_1, _2); } // CHECK-LABEL: @vfcmp_sle_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sle.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sle.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sle_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sle_d(_1, _2); } // CHECK-LABEL: @vfcmp_sle_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sle.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sle.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sle_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sle_s(_1, _2); } // CHECK-LABEL: @vfcmp_slt_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.slt.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.slt.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_slt_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_slt_d(_1, _2); } // CHECK-LABEL: @vfcmp_slt_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.slt.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.slt.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_slt_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_slt_s(_1, _2); } // CHECK-LABEL: @vfcmp_sne_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sne.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sne.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sne_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sne_d(_1, _2); } // CHECK-LABEL: @vfcmp_sne_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sne.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sne.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sne_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sne_s(_1, _2); } // CHECK-LABEL: @vfcmp_sor_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sor.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sor.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sor_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sor_d(_1, _2); } // CHECK-LABEL: @vfcmp_sor_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sor.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sor.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sor_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sor_s(_1, _2); } // CHECK-LABEL: @vfcmp_sueq_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sueq.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sueq.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sueq_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sueq_d(_1, _2); } // CHECK-LABEL: @vfcmp_sueq_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sueq.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sueq.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sueq_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sueq_s(_1, _2); } // CHECK-LABEL: @vfcmp_sule_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sule.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sule.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sule_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sule_d(_1, _2); } // CHECK-LABEL: @vfcmp_sule_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sule.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sule.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sule_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sule_s(_1, _2); } // CHECK-LABEL: @vfcmp_sult_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sult.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sult.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sult_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sult_d(_1, _2); } // CHECK-LABEL: @vfcmp_sult_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sult.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sult.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sult_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sult_s(_1, _2); } // CHECK-LABEL: @vfcmp_sun_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sun.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sun.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sun_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sun_d(_1, _2); } // CHECK-LABEL: @vfcmp_sune_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sune.d(<2 x double> [[_1:%.*]], <2 x double> [[_2:%.*]]) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <2 x double> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vfcmp.sune.d(<2 x double> [[TMP0]], <2 x double> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v2i64 vfcmp_sune_d(v2f64 _1, v2f64 _2) { return __builtin_lsx_vfcmp_sune_d(_1, _2); } // CHECK-LABEL: @vfcmp_sune_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sune.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sune.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sune_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sune_s(_1, _2); } // CHECK-LABEL: @vfcmp_sun_s( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sun.s(<4 x float> [[_1:%.*]], <4 x float> [[_2:%.*]]) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[_1_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[_2_COERCE:%.*]] to <4 x float> +// CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vfcmp.sun.s(<4 x float> [[TMP0]], <4 x float> [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +// CHECK-NEXT: ret i128 [[TMP3]] // v4i32 vfcmp_sun_s(v4f32 _1, v4f32 _2) { return __builtin_lsx_vfcmp_sun_s(_1, _2); @@ -5170,24 +7074,28 @@ v4i32 vfcmp_sun_s(v4f32 _1, v4f32 _2) { // CHECK-LABEL: @vrepli_b( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 1) -// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v16i8 vrepli_b() { return __builtin_lsx_vrepli_b(1); } // CHECK-LABEL: @vrepli_d( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 1) -// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v2i64 vrepli_d() { return __builtin_lsx_vrepli_d(1); } // CHECK-LABEL: @vrepli_h( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 1) -// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v8i16 vrepli_h() { return __builtin_lsx_vrepli_h(1); } // CHECK-LABEL: @vrepli_w( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 1) -// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to i128 +// CHECK-NEXT: ret i128 [[TMP1]] // v4i32 vrepli_w() { return __builtin_lsx_vrepli_w(1); } diff --git a/clang/test/CodeGen/Nontemporal.cpp b/clang/test/CodeGen/Nontemporal.cpp index e14ca18717928dcd4b007259b0e530ec168c5d0f..5052cb225d41116b9cc0f54c5bb3e27719610957 100644 --- a/clang/test/CodeGen/Nontemporal.cpp +++ b/clang/test/CodeGen/Nontemporal.cpp @@ -46,3 +46,17 @@ void test_all_sizes(void) // CHECK-LABEL: test_all_sizes vf2 = __builtin_nontemporal_load(&vf1); // CHECK: load <4 x float>{{.*}}align 16, !nontemporal vc2 = __builtin_nontemporal_load(&vc1); // CHECK: load <8 x i8>{{.*}}align 8, !nontemporal } + +struct S { char c[16]; }; +S x; + +typedef int v4si __attribute__ ((vector_size(16))); + +// CHECK-LABEL: define void @_Z14test_alignmentv() +// CHECK: load <4 x i32>, ptr @x, align 1, !nontemporal +// CHECK: store <4 x i32> %1, ptr @x, align 1, !nontemporal + +void test_alignment() { + auto t = __builtin_nontemporal_load((v4si*)x.c); + __builtin_nontemporal_store(t, (v4si*)x.c); +} diff --git a/clang/test/CodeGen/PowerPC/ppc-emmintrin.c b/clang/test/CodeGen/PowerPC/ppc-emmintrin.c index 15d291496c20a4a15d68623204c313fb85e34542..a3650beec625f2fc3912e38fc8a2a513ac814b4e 100644 --- a/clang/test/CodeGen/PowerPC/ppc-emmintrin.c +++ b/clang/test/CodeGen/PowerPC/ppc-emmintrin.c @@ -521,14 +521,14 @@ test_converts() { // CHECK: sitofp i64 %{{[0-9a-zA-Z_.]+}} to double // CHECK-LABEL: define available_externally <2 x i64> @_mm_cvtsi64_si128 -// CHECK: %[[INS:[0-9a-zA-Z_.]+]] = insertelement <2 x i64> undef, i64 %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[INS:[0-9a-zA-Z_.]+]] = insertelement <2 x i64> poison, i64 %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x i64> %[[INS]], i64 0, i32 1 // CHECK-LABEL: define available_externally <2 x double> @_mm_cvtsi64x_sd // CHECK: call <2 x double> @_mm_cvtsi64_sd(<2 x double> noundef %{{[0-9a-zA-Z_.]+}}, i64 noundef %{{[0-9a-zA-Z_.]+}}) // CHECK-LABEL: define available_externally <2 x i64> @_mm_cvtsi64x_si128 -// CHECK: %[[INS:[0-9a-zA-Z_.]+]] = insertelement <2 x i64> undef, i64 %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[INS:[0-9a-zA-Z_.]+]] = insertelement <2 x i64> poison, i64 %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x i64> %[[INS]], i64 0, i32 1 // CHECK-LABEL: define available_externally <2 x double> @_mm_cvtss_sd @@ -906,35 +906,35 @@ test_set() { // CHECK-LABEL: define available_externally <2 x i64> @_mm_set_epi16 // CHECK-COUNT-8: store i16 {{[0-9a-zA-Z_%.]+}}, ptr {{[0-9a-zA-Z_%.]+}}, align 2 -// CHECK: insertelement <8 x i16> undef, i16 {{[0-9a-zA-Z_%.]+}}, i32 0 +// CHECK: insertelement <8 x i16> poison, i16 {{[0-9a-zA-Z_%.]+}}, i32 0 // CHECK-COUNT-7: insertelement <8 x i16> {{[0-9a-zA-Z_%.]+}}, i16 {{[0-9a-zA-Z_%.]+}}, i32 {{[1-7]}} // CHECK-LABEL: define available_externally <2 x i64> @_mm_set_epi32 // CHECK-COUNT-4: store i32 {{[0-9a-zA-Z_%.]+}}, ptr {{[0-9a-zA-Z_%.]+}}, align 4 -// CHECK: insertelement <4 x i32> undef, i32 {{[0-9a-zA-Z_%.]+}}, i32 0 +// CHECK: insertelement <4 x i32> poison, i32 {{[0-9a-zA-Z_%.]+}}, i32 0 // CHECK-COUNT-3: insertelement <4 x i32> {{[0-9a-zA-Z_%.]+}}, i32 {{[0-9a-zA-Z_%.]+}}, i32 {{[1-3]}} // CHECK-LABEL: define available_externally <2 x i64> @_mm_set_epi64 // CHECK: call <2 x i64> @_mm_set_epi64x(i64 noundef %{{[0-9a-zA-Z_.]+}}, i64 noundef %{{[0-9a-zA-Z_.]+}}) // CHECK-LABEL: define available_externally <2 x i64> @_mm_set_epi64x -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x i64> undef, i64 %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x i64> poison, i64 %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x i64> %[[VEC]], i64 %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK-LABEL: define available_externally <2 x i64> @_mm_set_epi8 // CHECK-COUNT-16: store i8 {{[0-9a-zA-Z_%.]+}}, ptr {{[0-9a-zA-Z_%.]+}}, align 1 -// CHECK: insertelement <16 x i8> undef, i8 {{[0-9a-zA-Z_%.]+}}, i32 {{[0-9]+}} +// CHECK: insertelement <16 x i8> poison, i8 {{[0-9a-zA-Z_%.]+}}, i32 {{[0-9]+}} // CHECK-COUNT-15: {{[0-9a-zA-Z_%.]+}} = insertelement <16 x i8> {{[0-9a-zA-Z_%.]+}}, i8 {{[0-9a-zA-Z_%.]+}}, i32 {{[0-9]+}} // CHECK-LABEL: define available_externally <2 x double> @_mm_set_pd -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> undef, double %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> poison, double %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x double> %[[VEC]], double %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK-LABEL: define available_externally <2 x double> @_mm_set_pd1 // CHECK: call <2 x double> @_mm_set1_pd(double noundef %{{[0-9a-zA-Z_.]+}}) // CHECK-LABEL: define available_externally <2 x double> @_mm_set_sd -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> undef, double %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> poison, double %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x double> %[[VEC]], double 0.000000e+00, i32 1 // CHECK-LABEL: define available_externally <2 x i64> @_mm_set1_epi16 @@ -960,7 +960,7 @@ test_set() { // CHECK: call <2 x i64> @_mm_set_epi8 // CHECK-LABEL: define available_externally <2 x double> @_mm_set1_pd -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> undef, double %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> poison, double %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x double> %[[VEC]], double %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK-LABEL: define available_externally <2 x i64> @_mm_setr_epi16 @@ -981,7 +981,7 @@ test_set() { // CHECK: call <2 x i64> @_mm_set_epi8 // CHECK-LABEL: define available_externally <2 x double> @_mm_setr_pd -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> undef, double %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <2 x double> poison, double %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: insertelement <2 x double> %[[VEC]], double %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK-LABEL: define available_externally <2 x double> @_mm_setzero_pd() diff --git a/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c b/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c index ce002f001e1823c9fdd78683371ac1ed21ae7c8d..95dfd1202f1575780168f54417b934f14ae964f2 100644 --- a/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c +++ b/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c @@ -796,8 +796,8 @@ test_sad() { // CHECK-LABEL: define available_externally i64 @_mm_sad_pu8 // CHECK: call void @llvm.memset.p0.i64(ptr align 8 %{{[0-9a-zA-Z_.]+}}, i8 0, i64 8, i1 false) -// CHECK: insertelement <2 x i64> , i64 %{{[0-9a-zA-Z_.]+}}, i32 1 -// CHECK: insertelement <2 x i64> , i64 %{{[0-9a-zA-Z_.]+}}, i32 1 +// CHECK: insertelement <2 x i64> , i64 %{{[0-9a-zA-Z_.]+}}, i32 1 +// CHECK: insertelement <2 x i64> , i64 %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK: call <16 x i8> @vec_min(unsigned char vector[16], unsigned char vector[16]) // CHECK: call <16 x i8> @vec_max(unsigned char vector[16], unsigned char vector[16]) // CHECK: call <16 x i8> @vec_sub(unsigned char vector[16], unsigned char vector[16]) @@ -823,7 +823,7 @@ test_set() { // CHECK-LABEL: @test_set // CHECK-LABEL: define available_externally <4 x float> @_mm_set_ps -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> undef, float %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> poison, float %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: %[[VEC2:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC]], float %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK: %[[VEC3:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC2]], float %{{[0-9a-zA-Z_.]+}}, i32 2 // CHECK: %[[VEC4:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC3]], float %{{[0-9a-zA-Z_.]+}}, i32 3 @@ -833,21 +833,21 @@ test_set() { // CHECK: call <4 x float> @_mm_set1_ps // CHECK-LABEL: define available_externally <4 x float> @_mm_set_ss -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> undef, float %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> poison, float %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: %[[VEC2:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC]], float 0.000000e+00, i32 1 // CHECK: %[[VEC3:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC2]], float 0.000000e+00, i32 2 // CHECK: %[[VEC4:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC3]], float 0.000000e+00, i32 3 // CHECK: store <4 x float> %[[VEC4]], ptr %{{[0-9a-zA-Z_.]+}}, align 16 // CHECK-LABEL: define available_externally <4 x float> @_mm_set1_ps -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> undef, float %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> poison, float %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: %[[VEC2:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC]], float %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK: %[[VEC3:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC2]], float %{{[0-9a-zA-Z_.]+}}, i32 2 // CHECK: %[[VEC4:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC3]], float %{{[0-9a-zA-Z_.]+}}, i32 3 // CHECK: store <4 x float> %[[VEC4]], ptr %{{[0-9a-zA-Z_.]+}}, align 16 // CHECK-LABEL: define available_externally <4 x float> @_mm_setr_ps -// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> undef, float %{{[0-9a-zA-Z_.]+}}, i32 0 +// CHECK: %[[VEC:[0-9a-zA-Z_.]+]] = insertelement <4 x float> poison, float %{{[0-9a-zA-Z_.]+}}, i32 0 // CHECK: %[[VEC2:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC]], float %{{[0-9a-zA-Z_.]+}}, i32 1 // CHECK: %[[VEC3:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC2]], float %{{[0-9a-zA-Z_.]+}}, i32 2 // CHECK: %[[VEC4:[0-9a-zA-Z_.]+]] = insertelement <4 x float> %[[VEC3]], float %{{[0-9a-zA-Z_.]+}}, i32 3 diff --git a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbb.c b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbb.c index 3a421f8c6cd421d997de74927fccf4e8cff5eb36..fbc51b4bf144ae8062cf62aabd5519b027e04c5c 100644 --- a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbb.c +++ b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbb.c @@ -6,6 +6,8 @@ // RUN: -disable-O0-optnone | opt -S -passes=mem2reg \ // RUN: | FileCheck %s -check-prefix=RV64ZBB +#include + // RV32ZBB-LABEL: @orc_b_32( // RV32ZBB-NEXT: entry: // RV32ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.orc.b.i32(i32 [[A:%.*]]) @@ -16,8 +18,8 @@ // RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.orc.b.i32(i32 [[A:%.*]]) // RV64ZBB-NEXT: ret i32 [[TMP0]] // -unsigned int orc_b_32(unsigned int a) { - return __builtin_riscv_orc_b_32(a); +uint32_t orc_b_32(uint32_t a) { + return __riscv_orc_b_32(a); } #if __riscv_xlen == 64 @@ -26,8 +28,8 @@ unsigned int orc_b_32(unsigned int a) { // RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.orc.b.i64(i64 [[A:%.*]]) // RV64ZBB-NEXT: ret i64 [[TMP0]] // -unsigned long orc_b_64(unsigned long a) { - return __builtin_riscv_orc_b_64(a); +uint64_t orc_b_64(uint64_t a) { + return __riscv_orc_b_64(a); } #endif @@ -41,19 +43,19 @@ unsigned long orc_b_64(unsigned long a) { // RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[A:%.*]], i1 false) // RV64ZBB-NEXT: ret i32 [[TMP0]] // -unsigned int clz_32(unsigned int a) { - return __builtin_riscv_clz_32(a); +unsigned int clz_32(uint32_t a) { + return __riscv_clz_32(a); } #if __riscv_xlen == 64 // RV64ZBB-LABEL: @clz_64( // RV64ZBB-NEXT: entry: // RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[A:%.*]], i1 false) -// RV64ZBB-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -// RV64ZBB-NEXT: ret i32 [[CAST]] +// RV64ZBB-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 +// RV64ZBB-NEXT: ret i32 [[CAST_I]] // -unsigned int clz_64(unsigned long a) { - return __builtin_riscv_clz_64(a); +unsigned int clz_64(uint64_t a) { + return __riscv_clz_64(a); } #endif @@ -67,18 +69,44 @@ unsigned int clz_64(unsigned long a) { // RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 false) // RV64ZBB-NEXT: ret i32 [[TMP0]] // -unsigned int ctz_32(unsigned int a) { - return __builtin_riscv_ctz_32(a); +unsigned int ctz_32(uint32_t a) { + return __riscv_ctz_32(a); } #if __riscv_xlen == 64 // RV64ZBB-LABEL: @ctz_64( // RV64ZBB-NEXT: entry: // RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 false) -// RV64ZBB-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -// RV64ZBB-NEXT: ret i32 [[CAST]] +// RV64ZBB-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 +// RV64ZBB-NEXT: ret i32 [[CAST_I]] +// +unsigned int ctz_64(uint64_t a) { + return __riscv_ctz_64(a); +} +#endif + +// RV32ZBB-LABEL: @cpop_32( +// RV32ZBB-NEXT: entry: +// RV32ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]]) +// RV32ZBB-NEXT: ret i32 [[TMP0]] +// +// RV64ZBB-LABEL: @cpop_32( +// RV64ZBB-NEXT: entry: +// RV64ZBB-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]]) +// RV64ZBB-NEXT: ret i32 [[TMP0]] +// +unsigned int cpop_32(uint32_t a) { + return __riscv_cpop_32(a); +} + +#if __riscv_xlen == 64 +// RV64ZBB-LABEL: @cpop_64( +// RV64ZBB-NEXT: entry: +// RV64ZBB-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]]) +// RV64ZBB-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 +// RV64ZBB-NEXT: ret i32 [[CAST_I]] // -unsigned int ctz_64(unsigned long a) { - return __builtin_riscv_ctz_64(a); +unsigned int cpop_64(uint64_t a) { + return __riscv_cpop_64(a); } #endif diff --git a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c index ae9153eff155e196e97616cbdd092276b34e00b2..93db3a482ef2bc513469f4fb6be42e3128a0f67a 100644 --- a/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c +++ b/clang/test/CodeGen/RISCV/rvb-intrinsics/zbc.c @@ -6,7 +6,7 @@ // RUN: -disable-O0-optnone | opt -S -passes=mem2reg \ // RUN: | FileCheck %s -check-prefix=RV64ZBC -#include +#include #if __riscv_xlen == 64 // RV64ZBC-LABEL: @clmul_64( @@ -15,7 +15,7 @@ // RV64ZBC-NEXT: ret i64 [[TMP0]] // uint64_t clmul_64(uint64_t a, uint64_t b) { - return __builtin_riscv_clmul_64(a, b); + return __riscv_clmul_64(a, b); } // RV64ZBC-LABEL: @clmulh_64( @@ -24,7 +24,7 @@ uint64_t clmul_64(uint64_t a, uint64_t b) { // RV64ZBC-NEXT: ret i64 [[TMP0]] // uint64_t clmulh_64(uint64_t a, uint64_t b) { - return __builtin_riscv_clmulh_64(a, b); + return __riscv_clmulh_64(a, b); } // RV64ZBC-LABEL: @clmulr_64( @@ -33,7 +33,7 @@ uint64_t clmulh_64(uint64_t a, uint64_t b) { // RV64ZBC-NEXT: ret i64 [[TMP0]] // uint64_t clmulr_64(uint64_t a, uint64_t b) { - return __builtin_riscv_clmulr_64(a, b); + return __riscv_clmulr_64(a, b); } #endif @@ -48,7 +48,7 @@ uint64_t clmulr_64(uint64_t a, uint64_t b) { // RV64ZBC-NEXT: ret i32 [[TMP0]] // uint32_t clmul_32(uint32_t a, uint32_t b) { - return __builtin_riscv_clmul_32(a, b); + return __riscv_clmul_32(a, b); } #if __riscv_xlen == 32 @@ -58,7 +58,7 @@ uint32_t clmul_32(uint32_t a, uint32_t b) { // RV32ZBC-NEXT: ret i32 [[TMP0]] // uint32_t clmulh_32(uint32_t a, uint32_t b) { - return __builtin_riscv_clmulh_32(a, b); + return __riscv_clmulh_32(a, b); } // RV32ZBC-LABEL: @clmulr_32( @@ -67,6 +67,6 @@ uint32_t clmulh_32(uint32_t a, uint32_t b) { // RV32ZBC-NEXT: ret i32 [[TMP0]] // uint32_t clmulr_32(uint32_t a, uint32_t b) { - return __builtin_riscv_clmulr_32(a, b); + return __riscv_clmulr_32(a, b); } #endif diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmacc_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmacc_4x8x4.c index 935cb2e007d356436148b1840b11b1a3dfd84391..80e1c443eb54b4df95b7be2ba4a888b20c92573b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmacc_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmacc_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmacc_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmacc_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m1(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmacc_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmacc_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m2(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmacc_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmacc_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmacc_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmacc_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m8(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccsu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccsu_4x8x4.c index f34517b24bcf2051eec320c58f0e6ddc317ba25c..8c0a6218c1d2f875f35df02c15ec26edebc37385 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccsu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccsu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m1(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m2(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m8(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccu_4x8x4.c index ab7f6627ad1fb040e824f2e99c6c439c6879f561..b40891f417f2c9dc3dd9f79d71f0fdfe51f34d79 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccu_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccu_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m1(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccu_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccu_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m2(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccu_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccu_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccu_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccu_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m8(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccus_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccus_4x8x4.c index d0bcdcbf40cc324a47dcee969a5300069e03004d..d106aab64c514ebeb125ad349afda062400ac326 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccus_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vqmaccus_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccus_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccus_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m1(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccus_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccus_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m2(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccus_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccus_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccus_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccus_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m8(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdf.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdf.c index 7073c65233f65fcdd24081649989aa44f7a0ee11..76a9ddc0d5294651536ec95e1d18cee597f8cec6 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdf.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdf.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdm.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdm.c index 1b66240e9f2fcbc2151c9c7b7a6cca26979fe66e..468c3f18378d3c3dbd4eecb1e49a39ee31aba953 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdm.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesdm.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesef.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesef.c index c04092a5d9872a4601c32742e06a8d92dc38098d..bc6a17e4b6f0fba07b5bd53e0100540a59a963b8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesef.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesef.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesem.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesem.c index 88c33d87212fef1f7d1eae6c888734efe9f5a14f..e0e1662b76f9cb29cde526be865904ab5dc4a7e5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesem.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesem.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf1.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf1.c index 3ef9aa473fcc2e0563bb13e9d9ea70dfe149d628..4b3d247ac28093ab4960e2712741b9d0c83edd8e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf1.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf1.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf2.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf2.c index 94536358d51b067afc7b989d7b584cbf3482c457..9249057886c2fcbce0e81360bd4c0828da5aba77 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf2.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaeskf2.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesz.c index bad34e2eb441404e83ae129738abb197491bde36..0700b60fa639953e9fbeae9553e93341b76d38a4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vaesz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vandn.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vandn.c index 4901b9bb4fdf640515382abb86da5af760f9f398..1154ee27fe005218b6ebede40d7040f420904220 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vandn.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vandn.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev.c index 1e107dc37a2744427f54aa822e746685ddd825da..6b815bf66ef9906fe05847d1be35dc07e56c2f93 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev8.c index 471a0bb8a1df813181ada5ef4cfdbe775e76f5af..04a1e88a63f574e7bbb12f9eedb04b8d40b9a5ea 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vbrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmul.c index 54c9aa71f846b2d88b93e65b84ec180020dd6e1d..6137229e273c4c9f9ecddb46e37571fb8db891f3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmulh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmulh.c index cf10d2566eb627f160c37504cb0db34391bc4fc1..6c16de1297c06bf5bf3e7ac088c995a8d8941de3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmulh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclmulh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclz.c index 1f92b08e3f9598d77c8f1f03cec8f3b328777096..0910562a9342de12db32105d72caa6b6213ff838 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vclz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c index 69eaed4d184e5b314dac08d266146acb49b4b125..13748be1acc1ac9b2f04540e1e41a47cafc5addc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vctz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vctz.c index 26399c1ae7d4d27655072d5465099f3709f65b67..9aa10fc518d83f9fe6665d98e9ae88e03f05b817 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vctz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vctz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vghsh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vghsh.c index b8fc94b251b9361490129e412e4864874482dd24..54a9ebf7a6f5fd7ea5c37635863aaf8e0a182045 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vghsh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vghsh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vgmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vgmul.c index f78ac856cb65ad75dde45064b6b0a32356ad9a04..8b1000575ab0e395dbe16cf636988b4f611d1436 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vgmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vgmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrev8.c index b4187810de9f8f606fef4b58d7ebd253f8fde14b..f520f414b94071965bfbabc795e3cae4d28bc862 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrol.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrol.c index 4f64e5d6dc1fea717cdf4c4c0094d6f137fd5243..1c9a95522c6f4712b36dcf6bf82f17dd2c36e1e8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrol.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vrol.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vror.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vror.c index bf7a252950e1dcd95227cb87603b877e98c71a19..7b37a10bbbaa90676ead998e7d0426d800c4c3c5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vror.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vror.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ch.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ch.c index 52002081ddf6f98f8a9bb3bc38453a7fe7a182d3..6c33dab2ac494b2fcaa1d45762c29fbb7116f28b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ch.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ch.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2cl.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2cl.c index e07a3375e0f9708d53136f8a1c20d19f94183389..97f51b41a253964d5cd348efe7882258aa923a9c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2cl.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2cl.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ms.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ms.c index 0e3be9fdc43669303d186540b06549e61d90a959..021349f1d0a01d8783e3c7e2a984295fc3f9179d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ms.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsha2ms.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3c.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3c.c index c6d1fe99d6015cc811e1e756b403bdd4e8c14e74..f678476489306762a5155e31223880be05a9d86e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3c.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3c.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3me.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3me.c index cf0fa32a5c35347fd972b2f283782d4a448fc45d..e683c0f8a6712bd505ca44815917eba05cae6b04 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3me.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm3me.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4k.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4k.c index 110dc4c3268ecd3c4e67660737503144603db394..05b164d19d395178a9bdca0dedd7c183b7f140b4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4k.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4k.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4r.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4r.c index 1e8be7df16e8830c5207e04b9596de9c071d902a..f9d855a72d2885c75066ede8c9e8a8761d7d1f68 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4r.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsm4r.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vwsll.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vwsll.c index a4c92e1ca05d958fae0963ab07aba3549f45dd5c..dcc4e7b0e3e1e5ca078bac6af3bbf0ceb65ca19f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vwsll.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vwsll.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmacc_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmacc_4x8x4.c index 839d09c4f9a986a1f65f8dbd06710ab43b953ae5..88fae73069440035ce4bb56d343b9db09279624a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmacc_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmacc_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmacc_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmacc_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmacc_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmacc_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmacc_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmacc_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmacc_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmacc_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccsu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccsu_4x8x4.c index b18853043e9249a0f1834c796997466b0658ab7e..0aec4bfd9fe226488ad43952a739ec71029c4aa4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccsu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccsu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1(vint32m1_t vd, vint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2(vint32m2_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4(vint32m4_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8(vint32m8_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccu_4x8x4.c index 4cb966b08f237019bfe49652e288eb1b34a52924..81965e86f77c8363ab0341e59be5b1b1aa05d4d5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccu_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccu_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccu_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccu_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccu_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccu_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccu_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccu_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccus_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccus_4x8x4.c index f558151f88a3f2a7341ab4b4079f68027cb493db..f2544cf3ef2aee1deb0ab3d331a250a2a6474776 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccus_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vqmaccus_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m1 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccus_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccus_4x8x4_i32m1(vint32m1_t vd, vuint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m2 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccus_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccus_4x8x4_i32m2(vint32m2_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m4 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccus_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccus_4x8x4_i32m4(vint32m4_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m8 -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccus_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccus_4x8x4_i32m8(vint32m8_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdf.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdf.c index 59a01b3fc3ed0d2f555bc4b747dd0db40a9bec7e..9c91d2a1192d569001b459eb37bfe0d8ddc2a0ed 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdf.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdf.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdm.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdm.c index ff6cf16b1143b5390f2219bbc98a3358f25a908e..dac9eb38713b4d1cda1e01303af096593bc07dd7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdm.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesdm.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesef.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesef.c index 8c645d5bd1182d7dcffc79ccd6ddfa6e013ff9a7..01875afa525efc08e40241fb75cd06a2c94aaa6e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesef.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesef.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesem.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesem.c index 72f2e963433a520f922ec75538eafe931a0dc988..e9a0add21c92d5126ff6a186801884ba3d5b385c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesem.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesem.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf1.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf1.c index cc68e5466809726d643d27957749bb1c372bf193..e896fe146fec4c4fbde69ef408017293ea5e3790 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf1.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf1.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf2.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf2.c index 7c7b141728eb89e0ed7576cfbb9b8d8f9e30ab3e..7ece17b761d51d440436769c4bcc905aaeb00dbc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf2.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaeskf2.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesz.c index 8e596fb1685e109ccc115dad8248d97c0ecafe2d..c80e4ebce5e5b782e858f3fb66e8f6b82b9b3853 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vaesz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vandn.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vandn.c index 0092b9d7980a6f92f2d469a77ec37068be458b69..f3c592ad9960a9a11dd50ea8cb29f4cb10f07fa0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vandn.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vandn.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev.c index 0bb47a67a4bb4899f351cdab964e61853a0dd31c..8b9837d8d6a9ba21892afaca149332714dd4baf8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev8.c index 637c7139ccac7c941fca88e483ad30a86064880a..17a1545cdc0551af2efdafdaa9f1f9337fd4ed19 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vbrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmul.c index 46ac3c8a7c0e587bc9c0a5e92afaf3ebbc70e8c7..6eebab306bfbbae29fe60ec9e735544450c32b5f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmulh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmulh.c index af323c79680d19af6c08137537fcff6f13709738..03f8ee06cee4f73ae04c43bd256e33a3a100417a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmulh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclmulh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclz.c index 9ea5ac50e3c246511d744305157c5bb559b12108..6fd34da34ba4c219ecc30521fa096fcf67a3825f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vclz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c index d73d656264405ef6b4109c16b23b69b3d096aba1..adb0ac9ee5d79a3e4050a2fb5998d58719551be1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vctz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vctz.c index 4b54f2e41eed1241a634c19a22740a629416b4e2..d35814a09df66189989872e92de50945e8a1a9ee 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vctz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vctz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vghsh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vghsh.c index c30dde2e0fbff94e794df755eae4dd9cf7c5df8f..33cf128986c2d28b756784857c7bc032a291b4fb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vghsh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vghsh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vgmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vgmul.c index 3a78395e15271b59b0c8b0c6dd1bab0f21bab46d..a6b6de9b0673070d38c215d702dad0908f70b893 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vgmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vgmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrev8.c index c8b3ec5b445f5e915e87c928cb70659e2a69bd9e..c0cbfeabd141923370cc7b72fccdeb5a51a8d30f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrol.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrol.c index 672a35e972ddcb63e7dd1426f58d61d1917f777f..8775f1394156d43f5199b485dd1a07f5e3aa9ac0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrol.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vrol.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vror.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vror.c index 6d992da031a05e3ced900ae5535f38e6790a9f9e..746ca30300b996a319e23bc07eafec1882449c1c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vror.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vror.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ch.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ch.c index e10541af38be6b8885f9a0d9d3f35d5f6edabbb9..8b4056ae8215d0c59e0363c2678aa0287b1b345a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ch.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ch.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2cl.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2cl.c index c95138b174992eaa625c69007f0364291e5b95b5..bf70bd9d5834331c699e4db0e713031f175ccb02 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2cl.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2cl.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ms.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ms.c index b616b49f663a4950f7809dc00c985d7bb92a21d0..c129048f0d2bc6a46bdb99d091c653acb518887e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ms.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsha2ms.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3c.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3c.c index 3a3a8a62a11781db873e9832283ea171f5467e04..f65689e4301a513e29641ba0b36901c47892de91 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3c.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3c.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3me.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3me.c index 72837aeb5a66a069920314c8789ea54876f78a47..fb4fd66d2a7e12c5edf26b0654336922156a645c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3me.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm3me.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4k.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4k.c index b25b2ade5806fe5367e8dae3967fd8b253c9d298..eaf20d83637429769c12d1f7c3df4325bb19a036 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4k.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4k.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4r.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4r.c index 4eeecb894dda2bbb34fd1d53f031e02abf1e4d8e..cfc8532835eaa3a5252416c6df8d91a9e5eef1f1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4r.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vsm4r.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vwsll.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vwsll.c index 6cfdbabb0951574e2a81919378a3c3d5ce3f523e..c0a339e6f46cd9575ef8a970a203c4cc916d09af 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vwsll.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vwsll.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmacc_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmacc_4x8x4.c index 05c10840cabfaa51003ef8cafc7a00444371ce96..8fdeac62a31f106b89a883994182e53b1334bc3f 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmacc_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmacc_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmacc_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmacc_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m1_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmacc_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmacc_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m2_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmacc_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmacc_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmacc_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmacc_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_i32m8_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccsu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccsu_4x8x4.c index bce1a4e9443fd92660d4e586f9d437454dca4b78..e02c790dfbeb771999e57bca1466f5a6de73d79c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccsu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccsu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m1_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m2_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_i32m8_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccu_4x8x4.c index 36aaae9caebf60b7c2903e7af61a8f6f7d2223f0..ddeb6de0071647eb2be480a5ac91e0a9aa329983 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccu_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccu_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m1_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccu_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccu_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m2_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccu_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccu_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccu_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccu_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_i32m8_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccus_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccus_4x8x4.c index f5ac2bf0f1f3a75255d7218f75d1b6341cd45929..397e406c2ee58b0b9e4d3ffa4aee56c19b10bb67 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccus_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vqmaccus_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccus_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccus_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m1_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccus_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccus_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m2_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccus_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccus_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccus_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccus_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_i32m8_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdf.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdf.c index c75e3fa69453905e781912a1252021deeaf35b5e..8c18e323f7ceca225f58a82e504c64bd327c3675 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdf.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdf.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdm.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdm.c index b836ff37e58ab1db2a2a3c9372e55b8b5309ce23..7566be80e9d93df4098541d3187a954ce8eb5e89 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdm.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesdm.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesef.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesef.c index f5e47a9dee6d8337ae22f84008b507619212ea0a..ddeed6e78be1327e746e1229fd51d782cb097a5e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesef.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesef.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesem.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesem.c index 1f5281540d2d713d17988a780c6d5b658b665d65..2bd6350798f64348d0a1c96d409643602287a54d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesem.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesem.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf1.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf1.c index 1b94f3de632d02500b31e7772e9a20ce31c44be5..800541d4d42726743860c1f98acae7bb8a529102 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf1.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf1.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf2.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf2.c index 1be7a48707c33ad3d042e8de825310b7da474818..d55769b63de72aaa23545e7064eb9cd7f245eaad 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf2.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaeskf2.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesz.c index b4686e23c1a2798c28c9a56124d34af100d80080..101efd751f86e3f6310854536f38026fa903892a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vaesz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vandn.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vandn.c index 373e0b98fa326d57bfeb12d5a34787aef0f552b3..250a68503c837417f5533872900b4c52cb9457a3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vandn.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vandn.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev.c index 872d78295085fa5ecb18d46267525a2eddcc1f90..9ab69bedcfa4ad5b95a6e3dccbbd8e8015739241 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev8.c index 22c4afeea4fcc8662ea220d3e33e39a04e77868f..05cf75948760766a360f8d7901ceff4901804cb8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vbrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmul.c index 8c65318ccdaf38e0081d6fd70f88f89a8c07daf7..a4277ba9fa7d9b69ae37211d2493b55508c06db2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmulh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmulh.c index cdb4e942b85d2543736efc691c3b55f854ea4f99..dc0830d74239acfc625410f50a01008b1542f35e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmulh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclmulh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclz.c index 319dae3cfbffbf16d119d85c53e61d882c505f93..fcba519df8130065c30b467c22c9f0aee756d108 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vclz.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c index 61e74dc544ddf1f8295172a580bd30bbde458f3b..8a1f2e1beec1107121657d48f08161c7f1ce969e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vctz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vctz.c index aac53850513d93d06794be2ec153cf45ae08cbb2..3785c92950684a676ad145c2c80d5f43c8391160 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vctz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vctz.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vghsh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vghsh.c index a8deabe51636ebffdeb9df656d289a27d5b93b46..712d105f4458a8ea14eb1338259a0d7b13adb97a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vghsh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vghsh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vgmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vgmul.c index 6a145d47989471ca8cd98fc1133e261ff0815b85..2b2736510b0d61e13dc1df8531696315956d65e1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vgmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vgmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrev8.c index 075f23d6e4eb704fd928f8e40177da462b2ec185..56565fd604e959bd3cbd939fe771f77a6eaa4dfd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrol.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrol.c index d8777fc06762b07ec9aaa095ace730f1fca49c18..40a2ed01634488e95eebc0c1eadb41e545b0b3bc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrol.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vrol.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vror.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vror.c index 4a5d44b5becad2cb6c4da58fbca06d20dedd2c94..f37130a365d875bc80b6fc88b7e1e0f2703550dc 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vror.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vror.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ch.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ch.c index 2f6b10107b2d9c41b3a0bb4feb92d80afb5a4ad3..6cef23f6d933b8194828fd71fcda1cfa136328b7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ch.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ch.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2cl.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2cl.c index 3d7181bd08d101bf71fe97eb1c249540a85e7ad2..b21fecc313036e712b8e390585b1a46496e5bfcf 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2cl.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2cl.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ms.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ms.c index f5477374d3a5b63159c50d96ec7bfe47eb09d2b3..8644276915c86294c2808aae1b35730f3bce457b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ms.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsha2ms.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3c.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3c.c index e85ea154d691188e6ffee57a4ac8b5a3c9e994f2..0615be26022f95e449f73cc8ec0aa77a51dfe4bb 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3c.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3c.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3me.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3me.c index fe3d94bc0fddc6d97a0e1a5d6a2c6757f948faca..e454c77cb9706bf8c1ba9376af6ffa4400de023c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3me.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm3me.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4k.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4k.c index 2ee834858621b45c10138a54840a0d0a4902fa18..334758272308bd84640d0ba073a7fc288fe8c768 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4k.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4k.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4r.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4r.c index 4c8f35161a5d2a452e9f72033eb5e0e94806e5ef..c58f8d22d4601de639e882ca476b13d52cbf29a8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4r.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vsm4r.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vwsll.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vwsll.c index 9a70fc032f8adeb0045a84ea661a731c67262d3d..7cab28445536ccc820883b40e0decf1b83299276 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vwsll.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vwsll.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmacc_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmacc_4x8x4.c index 531bc2b2b9425356a5bf1420d42a561a906dcf05..7b3b25a203315a45a6398f71e7dc26946742ffdd 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmacc_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmacc_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmacc_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmacc_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmacc_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmacc_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmacc_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmacc_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmacc_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmacc.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmacc_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmacc_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmacc_4x8x4_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccsu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccsu_4x8x4.c index 23bba523aaa4428c8306540c1f1eae1887bf41be..2f3cbeec26fc9cd8e76d7097f15e18ff45fcf1f7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccsu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccsu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccsu_4x8x4_i32m1_tu(vint32m1_t vd, vint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccsu_4x8x4_i32m2_tu(vint32m2_t vd, vint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccsu_4x8x4_i32m4_tu(vint32m4_t vd, vint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccsu_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccsu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccsu_4x8x4_i32m8_tu(vint32m8_t vd, vint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccsu_4x8x4_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccu_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccu_4x8x4.c index 950688c6c7851a84c621ac7ee8acf1987e04f26f..1f2b2a1c8645179513007ebab33b4868be77c9e2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccu_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccu_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccu_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccu_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vuint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccu_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccu_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vuint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccu_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccu_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vuint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccu_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccu.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccu_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vuint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccu_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vuint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccu_4x8x4_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccus_4x8x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccus_4x8x4.c index 7bdce95043ee4ec4d9c65542fd4c053b680706c8..923234fe8e2b608edcae31b24b1d904e495786c2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccus_4x8x4.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vqmaccus_4x8x4.c @@ -7,41 +7,41 @@ #include // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m1_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv2i32.nxv8i8.nxv4i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m1_t test_sf_vqmaccus_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { +vint32m1_t test_sf_vqmaccus_4x8x4_i32m1_tu(vint32m1_t vd, vuint8m1_t vs1, vint8mf2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m2_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv4i32.nxv8i8.nxv8i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m2_t test_sf_vqmaccus_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { +vint32m2_t test_sf_vqmaccus_4x8x4_i32m2_tu(vint32m2_t vd, vuint8m1_t vs1, vint8m1_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m4_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv8i32.nxv8i8.nxv16i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m4_t test_sf_vqmaccus_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { +vint32m4_t test_sf_vqmaccus_4x8x4_i32m4_tu(vint32m4_t vd, vuint8m1_t vs1, vint8m2_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_tu(vd, vs1, vs2, vl); } // CHECK-RV64-LABEL: define dso_local @test_sf_vqmaccus_4x8x4_i32m8_tu -// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { // CHECK-RV64-NEXT: entry: -// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv64i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vqmaccus.4x8x4.nxv16i32.nxv8i8.nxv32i8.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) // CHECK-RV64-NEXT: ret [[TMP0]] // -vint32m8_t test_sf_vqmaccus_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vint8m8_t vs2, size_t vl) { +vint32m8_t test_sf_vqmaccus_4x8x4_i32m8_tu(vint32m8_t vd, vuint8m1_t vs1, vint8m4_t vs2, size_t vl) { return __riscv_sf_vqmaccus_4x8x4_tu(vd, vs1, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdf.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdf.c index c23649ce655479d77ccb5c536e93d47d2f369cac..34fd46465c34a84ad0a55536b85be1258766f27e 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdf.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdf.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdm.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdm.c index f7d66d754fde40a920cff452720ca3fe7cfef36f..2d0f8e7cafc7e88b6e2de982220df8469b7fcaec 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdm.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesdm.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesef.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesef.c index cf3fab73f076ec4a50f7b61549921ff3facb56b4..26518b9a709fec5e7766c782de543b3d65379e57 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesef.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesef.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesem.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesem.c index 8a93a7e5440a804cc164a2d65325a2db99513e1d..67e13665eea8439cc2a4f0abf32cd14e12a67b3b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesem.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesem.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf1.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf1.c index 8527cca1523187a8b2b93bf6074fe73d5ea5a361..d285545eda185b9bbce1caa9fd43fd3dddb344af 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf1.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf1.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf2.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf2.c index ec6bb1dd498a4871b73c405fcc396bfc21cb1519..5c73f2e442bfa4bb0cd03476110770e846d71e04 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf2.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaeskf2.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesz.c index de0ceaa06642122e329e8b492f2911f669be9c24..71698175d7b6b7a747a7a8191a73bf6060817e57 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vaesz.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vandn.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vandn.c index 3f32c1c8e7423eab51dd217f06e003a65570e57b..bf9df04de5dada4372e2ea04cd60dd51eaacbaf8 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vandn.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vandn.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev.c index b64e9660a971220ccb6c779ff8136da1cf5bb093..39463e8ba8344269e4c289f558b411f134bde65c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev8.c index f7064acc6af5f85d5edd815560e34b8ce20dd9fe..a0096aaed979e48430426b59b542e7e252b6b7be 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vbrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmul.c index 6aa9d6bf7f62fae67dc24ed81b1da719012e7c7c..e4f74a8dde9dac88c2aaf17170d92e290d0ae7ba 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmulh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmulh.c index 34ebdd2c44aa63c62c793745692abfbfc7de57b4..d5b992ae345fc39188a2424a3facedc7499aebb5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmulh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclmulh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclz.c index ba7ad3a9f5ec5446b858ec5c03a8f2e854d22a05..79d8c0533bebbc5b85832683a7ca6b04b1de39b2 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vclz.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c index 86b5915efd46a2226895f09aeb4dce9b30d3249a..02a499d4b67da54903b880f6a26efc0dfc7f17a5 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vctz.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vctz.c index 5aed53bafb4d398bd466194b762c08442fe6fddf..7f6a9afaebb0698d7e2608fcabd74def50a70142 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vctz.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vctz.c @@ -1,6 +1,18 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvbb -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vghsh.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vghsh.c index 59c957debaa7f9e533b0dbba24dd54f2c396c6ff..20d04101bf38c90e4661664afc239edd7f9a6aa0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vghsh.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vghsh.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vgmul.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vgmul.c index eae136b614321cec63acdb1b63babdeefe94c5ad..81b864a71bf603d12ab571e84e9efff1380b4f64 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vgmul.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vgmul.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrev8.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrev8.c index 0f9fe962bab39775dfb3d94bc2a02fc67ed378be..d0cc4b7020a2a8be4bcbbccc3c0f6e85063b43a3 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrev8.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrev8.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrol.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrol.c index d21e92248bd10499b325780451dc89e0585292d5..d2509c30ac66c6f1391a4d4dc233817e47e9f0fa 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrol.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vrol.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vror.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vror.c index b166d1096a0dc3f47032f9cc0bf13da42cb7e83b..4f916685d8b7b73a129d5d3593d63fb768f4b508 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vror.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vror.c @@ -1,14 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkb \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ch.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ch.c index baf99c80d3c85d7148cf5b396a956c0bc08a0f25..c9a89ebc5aef7c54e125df92810ecdf8a90fd00c 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ch.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ch.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2cl.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2cl.c index 05a61a4149053a181bc46840258720bbc3e586cf..81d32a176425fa60122e38413e896c89e1fc8825 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2cl.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2cl.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ms.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ms.c index b02aa384c850fbfbe555c25c40a633a025853bd0..5339c201122fcbe552a25d7ea202f4b5726a84e0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ms.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsha2ms.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3c.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3c.c index e01fcd1c1bc0f1a0e094d275a2eccc483fe9aecf..f88fc4dca19d9e902584d67ebe7d218603260ff4 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3c.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3c.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3me.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3me.c index 806d088faf109ce2f57201ad1611e4ba01771be5..239746c174c2b6b7dd9d8fe231ed4d1687638e6b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3me.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm3me.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4k.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4k.c index cd10883d3c132d132a2752afbe1fb03160fd873b..155a935723c69bde0da1f44d56da14e82f693584 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4k.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4k.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4r.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4r.c index 06d173ff269c7add94aecb2d959d84d4dd2bc09c..0df390bd0724a0eb3fcda654c098427940f21e73 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4r.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vsm4r.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vwsll.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vwsll.c index d6574c28dbef840642db885e8873d4cc29fad728..ea740944e1c9ee421357a41b57e3243167303121 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vwsll.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vwsll.c @@ -1,13 +1,16 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvl512b \ -// RUN: -target-feature +experimental-zvbb \ -// RUN: -target-feature +experimental-zvbc \ -// RUN: -target-feature +experimental-zvkg \ -// RUN: -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvknhb \ -// RUN: -target-feature +experimental-zvksed \ -// RUN: -target-feature +experimental-zvksh -disable-O0-optnone \ +// RUN: -target-feature +zvbb \ +// RUN: -target-feature +zvbc \ +// RUN: -target-feature +zvkb \ +// RUN: -target-feature +zvkg \ +// RUN: -target-feature +zvkned \ +// RUN: -target-feature +zvknhb \ +// RUN: -target-feature +zvksed \ +// RUN: -target-feature +zvksh \ +// RUN: -target-feature +experimental \ +// RUN: -disable-O0-optnone \ // RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ // RUN: FileCheck --check-prefix=CHECK-RV64 %s diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf1-out-of-range.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf1-out-of-range.c index 2062188634c4d643c1232823e434d7d885786b7d..ba3fa37566740e2c42bec9004a071b1f68521a42 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf1-out-of-range.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf1-out-of-range.c @@ -1,7 +1,7 @@ // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ -// RUN: -target-feature +v -target-feature +zfh -target-feature +experimental-zvfh \ -// RUN: -target-feature +experimental-zvkned -fsyntax-only -verify %s +// RUN: -target-feature +v -target-feature +zfh -target-feature +zvfh \ +// RUN: -target-feature +zvkned -target-feature +experimental -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf2-out-of-range.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf2-out-of-range.c index a0f8ad76c516af57d8c38ac022e16f2033499b7d..38907da7d66fd6e72a3ab78acae9a43d1d765689 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf2-out-of-range.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vaeskf2-out-of-range.c @@ -1,7 +1,7 @@ // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ -// RUN: -target-feature +v -target-feature +zfh -target-feature +experimental-zvfh \ -// RUN: -target-feature +experimental-zvkned -fsyntax-only -verify %s +// RUN: -target-feature +v -target-feature +zfh -target-feature +zvfh \ +// RUN: -target-feature +zvkned -target-feature +experimental -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c index 9d95acc33dddcdaf7dd3873c1c65cd468eea40de..582d5fd812bc34e62a52e123ebc6d813aad8e92d 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c @@ -21,19 +21,19 @@ unsigned long test_vlenb(void) { return __riscv_vlenb(); } //. -// RV32: attributes #0 = { mustprogress nofree noinline nosync nounwind willreturn memory(read) vscale_range(2,1024) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+32bit,+d,+f,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" } -// RV32: attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(read) } +// RV32: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(read) vscale_range(2,1024) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+32bit,+d,+f,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" } +// RV32: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree nosync nounwind willreturn memory(read) } //. -// RV64: attributes #0 = { mustprogress nofree noinline nosync nounwind willreturn memory(read) vscale_range(2,1024) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+d,+f,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" } -// RV64: attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(read) } +// RV64: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(read) vscale_range(2,1024) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+d,+f,+v,+zicsr,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" } +// RV64: attributes #[[ATTR1:[0-9]+]] = { mustprogress nocallback nofree nosync nounwind willreturn memory(read) } //. -// RV32: !0 = !{i32 1, !"wchar_size", i32 4} -// RV32: !1 = !{i32 1, !"target-abi", !"ilp32d"} -// RV32: !2 = !{i32 8, !"SmallDataLimit", i32 0} -// RV32: !3 = !{!"vlenb"} +// RV32: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// RV32: [[META1:![0-9]+]] = !{i32 1, !"target-abi", !"ilp32d"} +// RV32: [[META2:![0-9]+]] = !{i32 8, !"SmallDataLimit", i32 0} +// RV32: [[META3]] = !{!"vlenb"} //. -// RV64: !0 = !{i32 1, !"wchar_size", i32 4} -// RV64: !1 = !{i32 1, !"target-abi", !"lp64d"} -// RV64: !2 = !{i32 8, !"SmallDataLimit", i32 0} -// RV64: !3 = !{!"vlenb"} +// RV64: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// RV64: [[META1:![0-9]+]] = !{i32 1, !"target-abi", !"lp64d"} +// RV64: [[META2:![0-9]+]] = !{i32 8, !"SmallDataLimit", i32 0} +// RV64: [[META3]] = !{!"vlenb"} //. diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm3c-out-of-range.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm3c-out-of-range.c index a2238f01d2308426caafe31eb24a274e5073ea89..988f8aaf98b599df5f32bba623489b3ecd7133f0 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm3c-out-of-range.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm3c-out-of-range.c @@ -1,7 +1,7 @@ // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ -// RUN: -target-feature +v -target-feature +zfh -target-feature +experimental-zvfh \ -// RUN: -target-feature +experimental-zvksh -fsyntax-only -verify %s +// RUN: -target-feature +v -target-feature +zfh -target-feature +zvfh \ +// RUN: -target-feature +zvksh -target-feature +experimental -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm4k-out-of-range.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm4k-out-of-range.c index 56fa9ed53deb45104c87628ba8c34687331cf4d3..664b5afb734f62acfc5cc7af77df829b6befc1f7 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm4k-out-of-range.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vsm4k-out-of-range.c @@ -1,7 +1,7 @@ // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ -// RUN: -target-feature +v -target-feature +zfh -target-feature +experimental-zvfh \ -// RUN: -target-feature +experimental-zvksed -fsyntax-only -verify %s +// RUN: -target-feature +v -target-feature +zfh -target-feature +zvfh \ +// RUN: -target-feature +zvksed -target-feature +experimental -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-error2.c b/clang/test/CodeGen/SystemZ/builtins-systemz-error2.c index cf8ee6f7d002bbd1de30affb866dbb3a1c8c1c34..312a9a156d21eb88131680d4078c01906a78fae3 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-error2.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-error2.c @@ -1,11 +1,8 @@ // REQUIRES: systemz-registered-target // RUN: %clang_cc1 -triple s390x-ibm-linux -S -emit-llvm %s -verify -o - -typedef __attribute__((vector_size(16))) char v16i8; - -v16i8 f0(v16i8 a, v16i8 b) { - __builtin_tbegin ((void *)0); // expected-error {{'__builtin_tbegin' needs target feature transactional-execution}} - v16i8 tmp = __builtin_s390_vaq(a, b); // expected-error {{'__builtin_s390_vaq' needs target feature vector}} - return tmp; +__int128 f0(__int128 a, __int128 b) { + __builtin_tbegin ((void *)0); // expected-error {{'__builtin_tbegin' needs target feature transactional-execution}} + return __builtin_s390_vaq(a, b); // expected-error {{'__builtin_s390_vaq' needs target feature vector}} } diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-vector.c b/clang/test/CodeGen/SystemZ/builtins-systemz-vector.c index 877032a52a0ae4138fddd8c15d2721c5c0b25a53..31b8cd11ea79f662312e0d04db54a3ffd89fb563 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-vector.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-vector.c @@ -21,6 +21,8 @@ volatile vec_ushort vus; volatile vec_uint vui; volatile vec_ulong vul; volatile vec_double vd; +volatile signed __int128 si128; +volatile unsigned __int128 ui128; volatile unsigned int len; volatile unsigned char amt; @@ -111,14 +113,14 @@ void test_core(void) { } void test_integer(void) { - vuc = __builtin_s390_vaq(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vaq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - vuc = __builtin_s390_vacq(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vacq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - vuc = __builtin_s390_vaccq(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vaccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - vuc = __builtin_s390_vacccq(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vacccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + si128 = __builtin_s390_vaq(si128, si128); + // CHECK: call i128 @llvm.s390.vaq(i128 %{{.*}}, i128 %{{.*}}) + ui128 = __builtin_s390_vacq(ui128, ui128, ui128); + // CHECK: call i128 @llvm.s390.vacq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) + ui128 = __builtin_s390_vaccq(ui128, ui128); + // CHECK: call i128 @llvm.s390.vaccq(i128 %{{.*}}, i128 %{{.*}}) + ui128 = __builtin_s390_vacccq(ui128, ui128, ui128); + // CHECK: call i128 @llvm.s390.vacccq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) vuc = __builtin_s390_vaccb(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vaccb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) @@ -209,8 +211,8 @@ void test_integer(void) { // CHECK: call <4 x i32> @llvm.s390.vgfmh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) vul = __builtin_s390_vgfmf(vui, vui); // CHECK: call <2 x i64> @llvm.s390.vgfmf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) - vuc = __builtin_s390_vgfmg(vul, vul); - // CHECK: call <16 x i8> @llvm.s390.vgfmg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + ui128 = __builtin_s390_vgfmg(vul, vul); + // CHECK: call i128 @llvm.s390.vgfmg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) vus = __builtin_s390_vgfmab(vuc, vuc, vus); // CHECK: call <8 x i16> @llvm.s390.vgfmab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}}) @@ -218,8 +220,8 @@ void test_integer(void) { // CHECK: call <4 x i32> @llvm.s390.vgfmah(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}}) vul = __builtin_s390_vgfmaf(vui, vui, vul); // CHECK: call <2 x i64> @llvm.s390.vgfmaf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) - vuc = __builtin_s390_vgfmag(vul, vul, vuc); - // CHECK: call <16 x i8> @llvm.s390.vgfmag(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}) + ui128 = __builtin_s390_vgfmag(vul, vul, ui128); + // CHECK: call i128 @llvm.s390.vgfmag(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}) vsc = __builtin_s390_vmahb(vsc, vsc, vsc); // CHECK: call <16 x i8> @llvm.s390.vmahb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) @@ -308,14 +310,14 @@ void test_integer(void) { vul = __builtin_s390_vpopctg(vul); // CHECK: call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %{{.*}}) - vuc = __builtin_s390_vsq(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vsq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - vuc = __builtin_s390_vsbiq(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vsbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - vuc = __builtin_s390_vscbiq(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vscbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) - vuc = __builtin_s390_vsbcbiq(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vsbcbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + si128 = __builtin_s390_vsq(si128, si128); + // CHECK: call i128 @llvm.s390.vsq(i128 %{{.*}}, i128 %{{.*}}) + ui128 = __builtin_s390_vsbiq(ui128, ui128, ui128); + // CHECK: call i128 @llvm.s390.vsbiq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) + ui128 = __builtin_s390_vscbiq(ui128, ui128); + // CHECK: call i128 @llvm.s390.vscbiq(i128 %{{.*}}, i128 %{{.*}}) + ui128 = __builtin_s390_vsbcbiq(ui128, ui128, ui128); + // CHECK: call i128 @llvm.s390.vsbcbiq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) vuc = __builtin_s390_vscbib(vuc, vuc); // CHECK: call <16 x i8> @llvm.s390.vscbib(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) @@ -354,10 +356,10 @@ void test_integer(void) { // CHECK: call <2 x i64> @llvm.s390.vsumgh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) vul = __builtin_s390_vsumgf(vui, vui); // CHECK: call <2 x i64> @llvm.s390.vsumgf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) - vuc = __builtin_s390_vsumqf(vui, vui); - // CHECK: call <16 x i8> @llvm.s390.vsumqf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) - vuc = __builtin_s390_vsumqg(vul, vul); - // CHECK: call <16 x i8> @llvm.s390.vsumqg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + ui128 = __builtin_s390_vsumqf(vui, vui); + // CHECK: call i128 @llvm.s390.vsumqf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + ui128 = __builtin_s390_vsumqg(vul, vul); + // CHECK: call i128 @llvm.s390.vsumqg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) len = __builtin_s390_vtm(vuc, vuc); // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-vector2-error.c b/clang/test/CodeGen/SystemZ/builtins-systemz-vector2-error.c index cd27ac79e15d45bef87bc2491e9e37920de9d1f6..af3b4f191879e4dc3979fe5c450faee279091006 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-vector2-error.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-vector2-error.c @@ -23,14 +23,15 @@ volatile vec_uint vui; volatile vec_ulong vul; volatile vec_double vd; volatile vec_float vf; +volatile unsigned __int128 ui128; volatile unsigned int len; int cc; void test_integer(void) { - __builtin_s390_vmslg(vul, vul, vuc, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - __builtin_s390_vmslg(vul, vul, vuc, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} - __builtin_s390_vmslg(vul, vul, vuc, len); // expected-error {{must be a constant integer}} + __builtin_s390_vmslg(vul, vul, ui128, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + __builtin_s390_vmslg(vul, vul, ui128, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + __builtin_s390_vmslg(vul, vul, ui128, len);// expected-error {{must be a constant integer}} } void test_float(void) { diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-vector2.c b/clang/test/CodeGen/SystemZ/builtins-systemz-vector2.c index 5e287e28ed201fd70f01e4bb88bccc34b4325a55..3761f252d724bb2d2c63cc2537fb101238757fa5 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-vector2.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-vector2.c @@ -23,6 +23,7 @@ volatile vec_uint vui; volatile vec_ulong vul; volatile vec_double vd; volatile vec_float vf; +volatile unsigned __int128 ui128; volatile unsigned int len; const void * volatile cptr; @@ -41,10 +42,10 @@ void test_core(void) { } void test_integer(void) { - vuc = __builtin_s390_vmslg(vul, vul, vuc, 0); - // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 0) - vuc = __builtin_s390_vmslg(vul, vul, vuc, 15); - // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 15) + ui128 = __builtin_s390_vmslg(vul, vul, ui128, 0); + // CHECK: call i128 @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}, i32 0) + ui128 = __builtin_s390_vmslg(vul, vul, ui128, 15); + // CHECK: call i128 @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}, i32 15) } void test_float(void) { diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c index 07d6469d186645988d69a6e995ccfb7f6b07e04e..54a3365e03e32d1e43456234f49a9bbdaa89ff33 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c @@ -82,7 +82,7 @@ void test_core(void) { // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vd = vec_splat(vd, 1); - // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> + // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> // CHECK-ASM: vrepg vd = vec_splats(d); diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c index 0dc2fa7c66dd2200120a550c7b496934cccfb1d7..48d775b88878648d9f93ade6779a0eaf58b2da64 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c @@ -732,79 +732,79 @@ void test_core(void) { // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-ASM: vrepb vsc = vec_splat(vsc, 15); - // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> + // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> poison, <16 x i32> // CHECK-ASM: vrepb vuc = vec_splat(vuc, 0); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-ASM: vrepb vuc = vec_splat(vuc, 15); - // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> + // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> poison, <16 x i32> // CHECK-ASM: vrepb vbc = vec_splat(vbc, 0); // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-ASM: vrepb vbc = vec_splat(vbc, 15); - // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <16 x i32> + // CHECK: shufflevector <16 x i8> %{{.*}}, <16 x i8> poison, <16 x i32> // CHECK-ASM: vrepb vss = vec_splat(vss, 0); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-ASM: vreph vss = vec_splat(vss, 7); - // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> + // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> poison, <8 x i32> // CHECK-ASM: vreph vus = vec_splat(vus, 0); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-ASM: vreph vus = vec_splat(vus, 7); - // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> + // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> poison, <8 x i32> // CHECK-ASM: vreph vbs = vec_splat(vbs, 0); // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-ASM: vreph vbs = vec_splat(vbs, 7); - // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> undef, <8 x i32> + // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> poison, <8 x i32> // CHECK-ASM: vreph vsi = vec_splat(vsi, 0); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-ASM: vrepf vsi = vec_splat(vsi, 3); - // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> + // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> poison, <4 x i32> // CHECK-ASM: vrepf vui = vec_splat(vui, 0); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-ASM: vrepf vui = vec_splat(vui, 3); - // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> + // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> poison, <4 x i32> // CHECK-ASM: vrepf vbi = vec_splat(vbi, 0); // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-ASM: vrepf vbi = vec_splat(vbi, 3); - // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> undef, <4 x i32> + // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> poison, <4 x i32> // CHECK-ASM: vrepf vsl = vec_splat(vsl, 0); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vsl = vec_splat(vsl, 1); - // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> + // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> poison, <2 x i32> // CHECK-ASM: vrepg vul = vec_splat(vul, 0); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vul = vec_splat(vul, 1); - // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> + // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> poison, <2 x i32> // CHECK-ASM: vrepg vbl = vec_splat(vbl, 0); // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vbl = vec_splat(vbl, 1); - // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> undef, <2 x i32> + // CHECK: shufflevector <2 x i64> %{{.*}}, <2 x i64> poison, <2 x i32> // CHECK-ASM: vrepg vd = vec_splat(vd, 0); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vd = vec_splat(vd, 1); - // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> + // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> // CHECK-ASM: vrepg vsc = vec_splat_s8(-128); @@ -3413,16 +3413,15 @@ void test_integer(void) { // CHECK-ASM: vaccg vuc = vec_add_u128(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vaq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vaq vuc = vec_addc_u128(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vaccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vaccq(i128 %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vaccq vuc = vec_adde_u128(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vacq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vacq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vacq vuc = vec_addec_u128(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vacccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vacccq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vacccq vsc = vec_avg(vsc, vsc); @@ -3464,7 +3463,7 @@ void test_integer(void) { // CHECK: call <2 x i64> @llvm.s390.vgfmf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) // CHECK-ASM: vgfmf vuc = vec_gfmsum_128(vul, vul); - // CHECK: call <16 x i8> @llvm.s390.vgfmg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK: call i128 @llvm.s390.vgfmg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) // CHECK-ASM: vgfmg vus = vec_gfmsum_accum(vuc, vuc, vus); @@ -3477,7 +3476,7 @@ void test_integer(void) { // CHECK: call <2 x i64> @llvm.s390.vgfmaf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}}) // CHECK-ASM: vgfmaf vuc = vec_gfmsum_accum_128(vul, vul, vuc); - // CHECK: call <16 x i8> @llvm.s390.vgfmag(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vgfmag(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vgfmag vsc = vec_mladd(vsc, vsc, vsc); @@ -3633,16 +3632,15 @@ void test_integer(void) { // CHECK-ASM: vscbig vuc = vec_sub_u128(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vsq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vsq vuc = vec_subc_u128(vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vscbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vscbiq(i128 %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vscbiq vuc = vec_sube_u128(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vsbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vsbiq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vsbiq vuc = vec_subec_u128(vuc, vuc, vuc); - // CHECK: call <16 x i8> @llvm.s390.vsbcbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i128 @llvm.s390.vsbcbiq(i128 %{{.*}}, i128 %{{.*}}, i128 %{{.*}}) // CHECK-ASM: vsbcbiq vui = vec_sum4(vuc, vuc); @@ -3658,10 +3656,10 @@ void test_integer(void) { // CHECK: call <2 x i64> @llvm.s390.vsumgf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) // CHECK-ASM: vsumgf vuc = vec_sum_u128(vui, vui); - // CHECK: call <16 x i8> @llvm.s390.vsumqf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK: call i128 @llvm.s390.vsumqf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) // CHECK-ASM: vsumqf vuc = vec_sum_u128(vul, vul); - // CHECK: call <16 x i8> @llvm.s390.vsumqg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) + // CHECK: call i128 @llvm.s390.vsumqg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}) // CHECK-ASM: vsumqg idx = vec_test_mask(vsc, vuc); diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-constrained.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-constrained.c index 112bbac3394e976a6807ff7918e6e8c60d1c4737..750f5011a2679874d21a32666a6d580318eec3b8 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-constrained.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-constrained.c @@ -133,13 +133,13 @@ void test_core(void) { // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> poison, <4 x i32> zeroinitializer // CHECK-ASM: vrepf vf = vec_splat(vf, 1); - // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> + // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> poison, <4 x i32> // CHECK-ASM: vrepf vd = vec_splat(vd, 0); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vd = vec_splat(vd, 1); - // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> + // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> // CHECK-ASM: vrepg vf = vec_splats(f); diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-error.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-error.c index b7e0d77efca6d0a16f36ad4618718fddcc5e03cc..127b0f67e85c954c152da840b10f87eb489080d4 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-error.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-error.c @@ -126,9 +126,12 @@ void test_integer(void) { // expected-note@vecintrin.h:* 13 {{candidate function not viable}} // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}} - vuc = vec_msum_u128(vul, vul, vuc, idx); // expected-error {{must be a constant integer}} - vuc = vec_msum_u128(vul, vul, vuc, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}} - vuc = vec_msum_u128(vul, vul, vuc, 16); // expected-error-re {{argument value {{.*}} is outside the valid range}} + vuc = vec_msum_u128(vul, vul, vuc, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vmslg' must be a constant integer}} + // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}} + vuc = vec_msum_u128(vul, vul, vuc, -1); // expected-error {{no matching function}} expected-error {{argument value -1 is outside the valid range [0, 15]}} + // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}} + vuc = vec_msum_u128(vul, vul, vuc, 16); // expected-error {{no matching function}} expected-error {{argument value 16 is outside the valid range [0, 15]}} + // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}} } void test_float(void) { diff --git a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c index 416ca0ddd1b4fe29bc964a9a7acf5bbaeeb78a50..6c26b51c542e5db8a011d0fff5c2ca73008ac99b 100644 --- a/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c +++ b/clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c @@ -238,13 +238,13 @@ void test_core(void) { // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> poison, <4 x i32> zeroinitializer // CHECK-ASM: vrepf vf = vec_splat(vf, 1); - // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> + // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> poison, <4 x i32> // CHECK-ASM: vrepf vd = vec_splat(vd, 0); // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer // CHECK-ASM: vrepg vd = vec_splat(vd, 1); - // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> + // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> // CHECK-ASM: vrepg vf = vec_splats(f); @@ -661,16 +661,16 @@ void test_integer(void) { // CHECK-ASM: vtm vuc = vec_msum_u128(vul, vul, vuc, 0); - // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 0) + // CHECK: call i128 @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}, i32 0) // CHECK-ASM: vmslg vuc = vec_msum_u128(vul, vul, vuc, 4); - // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 4) + // CHECK: call i128 @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}, i32 4) // CHECK-ASM: vmslg vuc = vec_msum_u128(vul, vul, vuc, 8); - // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 8) + // CHECK: call i128 @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}, i32 8) // CHECK-ASM: vmslg vuc = vec_msum_u128(vul, vul, vuc, 12); - // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 12) + // CHECK: call i128 @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i128 %{{.*}}, i32 12) // CHECK-ASM: vmslg } diff --git a/clang/test/CodeGen/X86/avx-builtins.c b/clang/test/CodeGen/X86/avx-builtins.c index 9178ecaf3f8fe43e9a4826425b18675b50f0364f..d50366c3a022ccaf64bbc0eb1186e156e376b689 100644 --- a/clang/test/CodeGen/X86/avx-builtins.c +++ b/clang/test/CodeGen/X86/avx-builtins.c @@ -100,7 +100,7 @@ __m256 test_mm256_broadcast_ps(__m128* A) { __m256d test_mm256_broadcast_sd(double* A) { // CHECK-LABEL: test_mm256_broadcast_sd // CHECK: load double, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <4 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <4 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 1 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 2 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 3 @@ -110,7 +110,7 @@ __m256d test_mm256_broadcast_sd(double* A) { __m128 test_mm_broadcast_ss(float* A) { // CHECK-LABEL: test_mm_broadcast_ss // CHECK: load float, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 3 @@ -120,7 +120,7 @@ __m128 test_mm_broadcast_ss(float* A) { __m256 test_mm256_broadcast_ss(float* A) { // CHECK-LABEL: test_mm256_broadcast_ss // CHECK: load float, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <8 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <8 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 3 @@ -1481,7 +1481,7 @@ __m256i test_mm256_set_epi8(char A0, char A1, char A2, char A3, char A4, char A5 char A16, char A17, char A18, char A19, char A20, char A21, char A22, char A23, char A24, char A25, char A26, char A27, char A28, char A29, char A30, char A31) { // CHECK-LABEL: test_mm256_set_epi8 - // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -1519,7 +1519,7 @@ __m256i test_mm256_set_epi8(char A0, char A1, char A2, char A3, char A4, char A5 __m256i test_mm256_set_epi16(short A0, short A1, short A2, short A3, short A4, short A5, short A6, short A7, short A8, short A9, short A10, short A11, short A12, short A13, short A14, short A15) { // CHECK-LABEL: test_mm256_set_epi16 - // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -1540,7 +1540,7 @@ __m256i test_mm256_set_epi16(short A0, short A1, short A2, short A3, short A4, s __m256i test_mm256_set_epi32(int A0, int A1, int A2, int A3, int A4, int A5, int A6, int A7) { // CHECK-LABEL: test_mm256_set_epi32 - // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -1553,7 +1553,7 @@ __m256i test_mm256_set_epi32(int A0, int A1, int A2, int A3, int A4, int A5, int __m256i test_mm256_set_epi64x(long long A0, long long A1, long long A2, long long A3) { // CHECK-LABEL: test_mm256_set_epi64x - // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -1580,7 +1580,7 @@ __m256i test_mm256_set_m128i(__m128i A, __m128i B) { __m256d test_mm256_set_pd(double A0, double A1, double A2, double A3) { // CHECK-LABEL: test_mm256_set_pd - // CHECK: insertelement <4 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <4 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 1 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 2 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 3 @@ -1589,7 +1589,7 @@ __m256d test_mm256_set_pd(double A0, double A1, double A2, double A3) { __m256 test_mm256_set_ps(float A0, float A1, float A2, float A3, float A4, float A5, float A6, float A7) { // CHECK-LABEL: test_mm256_set_ps - // CHECK: insertelement <8 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <8 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 3 @@ -1602,7 +1602,7 @@ __m256 test_mm256_set_ps(float A0, float A1, float A2, float A3, float A4, float __m256i test_mm256_set1_epi8(char A) { // CHECK-LABEL: test_mm256_set1_epi8 - // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -1639,7 +1639,7 @@ __m256i test_mm256_set1_epi8(char A) { __m256i test_mm256_set1_epi16(short A) { // CHECK-LABEL: test_mm256_set1_epi16 - // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -1660,7 +1660,7 @@ __m256i test_mm256_set1_epi16(short A) { __m256i test_mm256_set1_epi32(int A) { // CHECK-LABEL: test_mm256_set1_epi32 - // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -1673,7 +1673,7 @@ __m256i test_mm256_set1_epi32(int A) { __m256i test_mm256_set1_epi64x(long long A) { // CHECK-LABEL: test_mm256_set1_epi64x - // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -1682,7 +1682,7 @@ __m256i test_mm256_set1_epi64x(long long A) { __m256d test_mm256_set1_pd(double A) { // CHECK-LABEL: test_mm256_set1_pd - // CHECK: insertelement <4 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <4 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 1 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 2 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 3 @@ -1691,7 +1691,7 @@ __m256d test_mm256_set1_pd(double A) { __m256 test_mm256_set1_ps(float A) { // CHECK-LABEL: test_mm256_set1_ps - // CHECK: insertelement <8 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <8 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 3 @@ -1707,7 +1707,7 @@ __m256i test_mm256_setr_epi8(char A0, char A1, char A2, char A3, char A4, char A char A16, char A17, char A18, char A19, char A20, char A21, char A22, char A23, char A24, char A25, char A26, char A27, char A28, char A29, char A30, char A31) { // CHECK-LABEL: test_mm256_setr_epi8 - // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -1745,7 +1745,7 @@ __m256i test_mm256_setr_epi8(char A0, char A1, char A2, char A3, char A4, char A __m256i test_mm256_setr_epi16(short A0, short A1, short A2, short A3, short A4, short A5, short A6, short A7, short A8, short A9, short A10, short A11, short A12, short A13, short A14, short A15) { // CHECK-LABEL: test_mm256_setr_epi16 - // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -1766,7 +1766,7 @@ __m256i test_mm256_setr_epi16(short A0, short A1, short A2, short A3, short A4, __m256i test_mm256_setr_epi32(int A0, int A1, int A2, int A3, int A4, int A5, int A6, int A7) { // CHECK-LABEL: test_mm256_setr_epi32 - // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -1779,7 +1779,7 @@ __m256i test_mm256_setr_epi32(int A0, int A1, int A2, int A3, int A4, int A5, in __m256i test_mm256_setr_epi64x(long long A0, long long A1, long long A2, long long A3) { // CHECK-LABEL: test_mm256_setr_epi64x - // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -1806,7 +1806,7 @@ __m256i test_mm256_setr_m128i(__m128i A, __m128i B) { __m256d test_mm256_setr_pd(double A0, double A1, double A2, double A3) { // CHECK-LABEL: test_mm256_setr_pd - // CHECK: insertelement <4 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <4 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 1 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 2 // CHECK: insertelement <4 x double> %{{.*}}, double %{{.*}}, i32 3 @@ -1815,7 +1815,7 @@ __m256d test_mm256_setr_pd(double A0, double A1, double A2, double A3) { __m256 test_mm256_setr_ps(float A0, float A1, float A2, float A3, float A4, float A5, float A6, float A7) { // CHECK-LABEL: test_mm256_setr_ps - // CHECK: insertelement <8 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <8 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <8 x float> %{{.*}}, float %{{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/avx512-error.c b/clang/test/CodeGen/X86/avx512-error.c index 99824a373e8ebfd2b4fc4a735e30955e72c6813b..422cc7a8679dcf656e164e04810956ac0f583d63 100644 --- a/clang/test/CodeGen/X86/avx512-error.c +++ b/clang/test/CodeGen/X86/avx512-error.c @@ -1,21 +1,24 @@ -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=1 -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=2 -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -emit-llvm -o /dev/null -verify -DFEATURE_TEST=3 -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-256 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=1 -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-256 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=2 -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-512 -emit-llvm -o /dev/null -verify -DFEATURE_TEST=3 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify=noevex +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -emit-llvm -o /dev/null -verify +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-256 -emit-llvm -o /dev/null -verify=noevex +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-512 -emit-llvm -o /dev/null -verify #include -#if FEATURE_TEST & 3 -// expected-no-diagnostics -#endif +// No error emitted whether we have "evex512" feature or not. +__attribute__((target("avx512bw,no-evex512"))) +__mmask64 k64_verify_1(__mmask64 a) { + return _knot_mask64(a); // expected-no-diagnostics +} + +__mmask64 k64_verify_2(__mmask64 a) { + return _knot_mask64(a); // expected-no-diagnostic +} -#if FEATURE_TEST & 1 __attribute__((target("avx512bw,evex512"))) __m512d zmm_verify_ok(__m512d a) { // No error emitted if we have "evex512" feature. - return __builtin_ia32_sqrtpd512(a, _MM_FROUND_CUR_DIRECTION); + return __builtin_ia32_sqrtpd512(a, _MM_FROUND_CUR_DIRECTION); // expected-no-diagnostic } __m512d zmm_error(__m512d a) { @@ -27,24 +30,3 @@ __m512d zmm_error(__m512d a) { // noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} // noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} #endif -#endif - -#if FEATURE_TEST & 2 -__attribute__((target("avx512bw,evex512"))) -__mmask64 k64_verify_ok(__mmask64 a) { - // No error emitted if we have "evex512" feature. - return _knot_mask64(a); -} -#if defined(__AVX10_1__) && !defined(__AVX10_1_512__) -// noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} -// noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} -// noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} -// noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} -// noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} -// noevex-warning@*:* {{invalid feature combination: +avx512bw +avx10.1-256; will be promoted to avx10.1-512}} -#endif - -__mmask64 test_knot_mask64(__mmask64 a) { - return _knot_mask64(a); // noevex-error {{always_inline function '_knot_mask64' requires target feature 'evex512', but would be inlined into function 'test_knot_mask64' that is compiled without support for 'evex512'}} -} -#endif diff --git a/clang/test/CodeGen/X86/avx512bw-builtins.c b/clang/test/CodeGen/X86/avx512bw-builtins.c index b61933f1a8cbee06c9e8cf9fef11327238a03de3..f82a5d17b292ac89ff21ff763a0cb68d5cab7d86 100644 --- a/clang/test/CodeGen/X86/avx512bw-builtins.c +++ b/clang/test/CodeGen/X86/avx512bw-builtins.c @@ -1889,7 +1889,7 @@ __m512i test_mm512_maskz_mov_epi8(__mmask64 __U, __m512i __A) { __m512i test_mm512_mask_set1_epi8(__m512i __O, __mmask64 __M, char __A) { // CHECK-LABEL: @test_mm512_mask_set1_epi8 - // CHECK: insertelement <64 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <64 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -1957,7 +1957,7 @@ __m512i test_mm512_mask_set1_epi8(__m512i __O, __mmask64 __M, char __A) { __m512i test_mm512_maskz_set1_epi8(__mmask64 __M, char __A) { // CHECK-LABEL: @test_mm512_maskz_set1_epi8 - // CHECK: insertelement <64 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <64 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <64 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -2228,7 +2228,7 @@ __m512i test_mm512_maskz_broadcastw_epi16(__mmask32 __M, __m128i __A) { __m512i test_mm512_mask_set1_epi16(__m512i __O, __mmask32 __M, short __A) { // CHECK-LABEL: @test_mm512_mask_set1_epi16 - // CHECK: insertelement <32 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -2266,7 +2266,7 @@ __m512i test_mm512_mask_set1_epi16(__m512i __O, __mmask32 __M, short __A) { __m512i test_mm512_maskz_set1_epi16(__mmask32 __M, short __A) { // CHECK-LABEL: @test_mm512_maskz_set1_epi16 - // CHECK: insertelement <32 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <32 x i16> %{{.*}}, i16 %{{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/avx512cd-builtins.c b/clang/test/CodeGen/X86/avx512cd-builtins.c index b15126808b801948336ab948f7654664fe04b096..3c1415cd6256551176dfd2d7b0f76341ae59b5f8 100644 --- a/clang/test/CodeGen/X86/avx512cd-builtins.c +++ b/clang/test/CodeGen/X86/avx512cd-builtins.c @@ -76,7 +76,7 @@ __m512i test_mm512_broadcastmb_epi64(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm512_broadcastmb_epi64 // CHECK: icmp eq <8 x i64> %{{.*}}, %{{.*}} // CHECK: zext i8 %{{.*}} to i64 - // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -91,7 +91,7 @@ __m512i test_mm512_broadcastmw_epi32(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm512_broadcastmw_epi32 // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}} // CHECK: zext i16 %{{.*}} to i32 - // CHECK: insertelement <16 x i32> undef, i32 %{{.*}} + // CHECK: insertelement <16 x i32> poison, i32 %{{.*}} // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} diff --git a/clang/test/CodeGen/X86/avx512f-builtins.c b/clang/test/CodeGen/X86/avx512f-builtins.c index a661c5235950349a139f74ea55cd13e086ad7b33..0e3463849951ed4836630d7e7ed8b73cc6c2d2ba 100644 --- a/clang/test/CodeGen/X86/avx512f-builtins.c +++ b/clang/test/CodeGen/X86/avx512f-builtins.c @@ -10077,7 +10077,7 @@ __m512i test_mm512_maskz_min_epu64 (__mmask8 __M, __m512i __A, __m512i __B) __m512i test_mm512_mask_set1_epi32 (__m512i __O, __mmask16 __M, int __A) { // CHECK-LABEL: @test_mm512_mask_set1_epi32 - // CHECK: insertelement <16 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -10100,7 +10100,7 @@ __m512i test_mm512_mask_set1_epi32 (__m512i __O, __mmask16 __M, int __A) __m512i test_mm512_maskz_set1_epi32(__mmask16 __M, int __A) { // CHECK-LABEL: @test_mm512_maskz_set1_epi32 - // CHECK: insertelement <16 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -10319,7 +10319,7 @@ __m512i test_mm512_setr_epi32 (int __A, int __B, int __C, int __D, __m512i test_mm512_mask_set1_epi64 (__m512i __O, __mmask8 __M, long long __A) { // CHECK-LABEL: @test_mm512_mask_set1_epi64 - // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -10334,7 +10334,7 @@ __m512i test_mm512_mask_set1_epi64 (__m512i __O, __mmask8 __M, long long __A) __m512i test_mm512_maskz_set1_epi64 (__mmask8 __M, long long __A) { // CHECK-LABEL: @test_mm512_maskz_set1_epi64 - // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/avx512fp16-builtins.c b/clang/test/CodeGen/X86/avx512fp16-builtins.c index 23bd0d3df3f2f38544d21c4c259aad9814e436ac..a766476ca92bd1628d1d1234a176348862cee209 100644 --- a/clang/test/CodeGen/X86/avx512fp16-builtins.c +++ b/clang/test/CodeGen/X86/avx512fp16-builtins.c @@ -1606,7 +1606,7 @@ short test_mm_cvtsi128_si16(__m128i A) { __m128i test_mm_cvtsi16_si128(short A) { // CHECK-LABEL: test_mm_cvtsi16_si128 - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 3 diff --git a/clang/test/CodeGen/X86/avx512vl-builtins.c b/clang/test/CodeGen/X86/avx512vl-builtins.c index 1d55f705ce64fa49be82aece00b647f225317561..6f544c21e798de910a4c986eaa93a4b57e35f2ce 100644 --- a/clang/test/CodeGen/X86/avx512vl-builtins.c +++ b/clang/test/CodeGen/X86/avx512vl-builtins.c @@ -6668,7 +6668,7 @@ __m256d test_mm256_maskz_movedup_pd(__mmask8 __U, __m256d __A) { __m128i test_mm_mask_set1_epi32(__m128i __O, __mmask8 __M) { // CHECK-LABEL: @test_mm_mask_set1_epi32 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}32 1 // CHECK: insertelement <4 x i32> %{{.*}}32 2 // CHECK: insertelement <4 x i32> %{{.*}}32 3 @@ -6679,7 +6679,7 @@ __m128i test_mm_mask_set1_epi32(__m128i __O, __mmask8 __M) { __m128i test_mm_maskz_set1_epi32(__mmask8 __M) { // CHECK-LABEL: @test_mm_maskz_set1_epi32 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}32 1 // CHECK: insertelement <4 x i32> %{{.*}}32 2 // CHECK: insertelement <4 x i32> %{{.*}}32 3 @@ -6690,7 +6690,7 @@ __m128i test_mm_maskz_set1_epi32(__mmask8 __M) { __m256i test_mm256_mask_set1_epi32(__m256i __O, __mmask8 __M) { // CHECK-LABEL: @test_mm256_mask_set1_epi32 - // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -6704,7 +6704,7 @@ __m256i test_mm256_mask_set1_epi32(__m256i __O, __mmask8 __M) { __m256i test_mm256_maskz_set1_epi32(__mmask8 __M) { // CHECK-LABEL: @test_mm256_maskz_set1_epi32 - // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -6718,7 +6718,7 @@ __m256i test_mm256_maskz_set1_epi32(__mmask8 __M) { __m128i test_mm_mask_set1_epi64(__m128i __O, __mmask8 __M, long long __A) { // CHECK-LABEL: @test_mm_mask_set1_epi64 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <2 x i32> // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} @@ -6727,7 +6727,7 @@ __m128i test_mm_mask_set1_epi64(__m128i __O, __mmask8 __M, long long __A) { __m128i test_mm_maskz_set1_epi64(__mmask8 __M, long long __A) { // CHECK-LABEL: @test_mm_maskz_set1_epi64 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <2 x i32> // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} @@ -6736,7 +6736,7 @@ __m128i test_mm_maskz_set1_epi64(__mmask8 __M, long long __A) { __m256i test_mm256_mask_set1_epi64(__m256i __O, __mmask8 __M, long long __A) { // CHECK-LABEL: @test_mm256_mask_set1_epi64 - // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -6747,7 +6747,7 @@ __m256i test_mm256_mask_set1_epi64(__m256i __O, __mmask8 __M, long long __A) { __m256i test_mm256_maskz_set1_epi64(__mmask8 __M, long long __A) { // CHECK-LABEL: @test_mm256_maskz_set1_epi64 - // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/avx512vlbw-builtins.c b/clang/test/CodeGen/X86/avx512vlbw-builtins.c index 3ef2df5a37c380bf9b78444c3397473347018c5b..e2ce348d0e077fe506d2090499e6b76f79ddd18c 100644 --- a/clang/test/CodeGen/X86/avx512vlbw-builtins.c +++ b/clang/test/CodeGen/X86/avx512vlbw-builtins.c @@ -2832,7 +2832,7 @@ __m256i test_mm256_maskz_broadcastw_epi16(__mmask16 __M, __m128i __A) { } __m128i test_mm_mask_set1_epi8 (__m128i __O, __mmask16 __M, char __A){ // CHECK-LABEL: @test_mm_mask_set1_epi8 - // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -2853,7 +2853,7 @@ __m128i test_mm_mask_set1_epi8 (__m128i __O, __mmask16 __M, char __A){ } __m128i test_mm_maskz_set1_epi8 ( __mmask16 __M, char __A){ // CHECK-LABEL: @test_mm_maskz_set1_epi8 - // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -2875,7 +2875,7 @@ __m128i test_mm_maskz_set1_epi8 ( __mmask16 __M, char __A){ __m256i test_mm256_mask_set1_epi8(__m256i __O, __mmask32 __M, char __A) { // CHECK-LABEL: @test_mm256_mask_set1_epi8 - // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -2913,7 +2913,7 @@ __m256i test_mm256_mask_set1_epi8(__m256i __O, __mmask32 __M, char __A) { __m256i test_mm256_maskz_set1_epi8( __mmask32 __M, char __A) { // CHECK-LABEL: @test_mm256_maskz_set1_epi8 - // CHECK: insertelement <32 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <32 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -2952,7 +2952,7 @@ __m256i test_mm256_maskz_set1_epi8( __mmask32 __M, char __A) { __m256i test_mm256_mask_set1_epi16(__m256i __O, __mmask16 __M, short __A) { // CHECK-LABEL: @test_mm256_mask_set1_epi16 - // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -2974,7 +2974,7 @@ __m256i test_mm256_mask_set1_epi16(__m256i __O, __mmask16 __M, short __A) { __m256i test_mm256_maskz_set1_epi16(__mmask16 __M, short __A) { // CHECK-LABEL: @test_mm256_maskz_set1_epi16 - // CHECK: insertelement <16 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -2996,7 +2996,7 @@ __m256i test_mm256_maskz_set1_epi16(__mmask16 __M, short __A) { __m128i test_mm_mask_set1_epi16(__m128i __O, __mmask8 __M, short __A) { // CHECK-LABEL: @test_mm_mask_set1_epi16 - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -3010,7 +3010,7 @@ __m128i test_mm_mask_set1_epi16(__m128i __O, __mmask8 __M, short __A) { __m128i test_mm_maskz_set1_epi16(__mmask8 __M, short __A) { // CHECK-LABEL: @test_mm_maskz_set1_epi16 - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/avx512vlcd-builtins.c b/clang/test/CodeGen/X86/avx512vlcd-builtins.c index 15f9c7ac299bf28f5ebdb58b60e8876638272cf9..b784809810e3d96f59a3ca23190543ebed339b9e 100644 --- a/clang/test/CodeGen/X86/avx512vlcd-builtins.c +++ b/clang/test/CodeGen/X86/avx512vlcd-builtins.c @@ -8,7 +8,7 @@ __m128i test_mm_broadcastmb_epi64(__m128i a,__m128i b) { // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}} // CHECK: shufflevector <4 x i1> %{{.*}}, <4 x i1> zeroinitializer, <8 x i32> // CHECK: zext i8 %{{.*}} to i64 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 return _mm_broadcastmb_epi64(_mm_cmpeq_epi32_mask (a, b)); } @@ -18,7 +18,7 @@ __m256i test_mm256_broadcastmb_epi64(__m256i a, __m256i b) { // CHECK: icmp eq <4 x i64> %{{.*}}, %{{.*}} // CHECK: shufflevector <4 x i1> %{{.*}}, <4 x i1> zeroinitializer, <8 x i32> // CHECK: zext i8 %{{.*}} to i64 - // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 @@ -29,7 +29,7 @@ __m128i test_mm_broadcastmw_epi32(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm_broadcastmw_epi32 // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}} // CHECK: zext i16 %{{.*}} to i32 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -40,7 +40,7 @@ __m256i test_mm256_broadcastmw_epi32(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm256_broadcastmw_epi32 // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}} // CHECK: zext i16 %{{.*}} to i32 - // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/f16c-builtins-constrained.c b/clang/test/CodeGen/X86/f16c-builtins-constrained.c index 51b23df21e0c1951fc14442cdba98bb0e5a81eb7..d616fa56fb71a7dda87388fc5cc995da0aae1607 100644 --- a/clang/test/CodeGen/X86/f16c-builtins-constrained.c +++ b/clang/test/CodeGen/X86/f16c-builtins-constrained.c @@ -5,7 +5,7 @@ float test_cvtsh_ss(unsigned short a) { // CHECK-LABEL: test_cvtsh_ss - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 3 @@ -21,7 +21,7 @@ float test_cvtsh_ss(unsigned short a) { unsigned short test_cvtss_sh(float a) { // CHECK-LABEL: test_cvtss_sh - // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float %{{.*}}, i32 0 // CHECK: call float @llvm.experimental.constrained.sitofp.f32.i32(i32 0, metadata !"round.tonearest", metadata !"fpexcept.strict") // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: call float @llvm.experimental.constrained.sitofp.f32.i32(i32 0, metadata !"round.tonearest", metadata !"fpexcept.strict") diff --git a/clang/test/CodeGen/X86/f16c-builtins.c b/clang/test/CodeGen/X86/f16c-builtins.c index 20b6013647ca513f64a45e4aeec3a7fd083ee36c..7f2fda654649e44e492cd5149e9d1cfffce81360 100644 --- a/clang/test/CodeGen/X86/f16c-builtins.c +++ b/clang/test/CodeGen/X86/f16c-builtins.c @@ -5,7 +5,7 @@ float test_cvtsh_ss(unsigned short a) { // CHECK-LABEL: test_cvtsh_ss - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 3 @@ -21,7 +21,7 @@ float test_cvtsh_ss(unsigned short a) { unsigned short test_cvtss_sh(float a) { // CHECK-LABEL: test_cvtss_sh - // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 1 // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 2 // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 3 diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c index b4b8f5dc0b8c55539afa76d803236f1a2182cdea..a1c90d71c8ebf58e066a7005b0ac45891f023e02 100644 --- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c +++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c @@ -145,7 +145,7 @@ unsigned __int64 test__shiftleft128(unsigned __int64 l, unsigned __int64 h, unsigned char d) { return __shiftleft128(l, h, d); } -// CHECK-X64-LABEL: define dso_local i64 @test__shiftleft128(i64 noundef %l, i64 noundef %h, i8 noundef %d) +// CHECK-X64-LABEL: define dso_local noundef i64 @test__shiftleft128(i64 noundef %l, i64 noundef %h, i8 noundef %d) // CHECK-X64: = zext i8 %{{.*}} to i64 // CHECK-X64: = tail call i64 @llvm.fshl.i64(i64 %h, i64 %l, i64 %{{.*}}) // CHECK-X64: ret i64 % @@ -154,7 +154,7 @@ unsigned __int64 test__shiftright128(unsigned __int64 l, unsigned __int64 h, unsigned char d) { return __shiftright128(l, h, d); } -// CHECK-X64-LABEL: define dso_local i64 @test__shiftright128(i64 noundef %l, i64 noundef %h, i8 noundef %d) +// CHECK-X64-LABEL: define dso_local noundef i64 @test__shiftright128(i64 noundef %l, i64 noundef %h, i8 noundef %d) // CHECK-X64: = zext i8 %{{.*}} to i64 // CHECK-X64: = tail call i64 @llvm.fshr.i64(i64 %h, i64 %l, i64 %{{.*}}) // CHECK-X64: ret i64 % diff --git a/clang/test/CodeGen/X86/sse-builtins.c b/clang/test/CodeGen/X86/sse-builtins.c index 885c82856522d2ad4e01bee9412cecb3ca331754..830081296e52fb839738d9da3079596e9b765aea 100644 --- a/clang/test/CodeGen/X86/sse-builtins.c +++ b/clang/test/CodeGen/X86/sse-builtins.c @@ -375,7 +375,7 @@ __m128 test_mm_load_ps(float* y) { __m128 test_mm_load_ps1(float* y) { // CHECK-LABEL: test_mm_load_ps1 // CHECK: load float, ptr %{{.*}}, align 4 - // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 3 @@ -385,7 +385,7 @@ __m128 test_mm_load_ps1(float* y) { __m128 test_mm_load_ss(float* y) { // CHECK-LABEL: test_mm_load_ss // CHECK: load float, ptr {{.*}}, align 1{{$}} - // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 1 // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 2 // CHECK: insertelement <4 x float> %{{.*}}, float 0.000000e+00, i32 3 @@ -395,7 +395,7 @@ __m128 test_mm_load_ss(float* y) { __m128 test_mm_load1_ps(float* y) { // CHECK-LABEL: test_mm_load1_ps // CHECK: load float, ptr %{{.*}}, align 4 - // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float %{{.*}}, i32 0 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 1 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 2 // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 3 @@ -566,7 +566,7 @@ void test_MM_SET_FLUSH_ZERO_MODE(unsigned int A) { __m128 test_mm_set_ps(float A, float B, float C, float D) { // CHECK-LABEL: test_mm_set_ps - // CHECK: insertelement <4 x float> undef, float {{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float {{.*}}, i32 0 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 1 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 2 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 3 @@ -575,7 +575,7 @@ __m128 test_mm_set_ps(float A, float B, float C, float D) { __m128 test_mm_set_ps1(float A) { // CHECK-LABEL: test_mm_set_ps1 - // CHECK: insertelement <4 x float> undef, float {{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float {{.*}}, i32 0 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 1 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 2 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 3 @@ -595,7 +595,7 @@ void test_MM_SET_ROUNDING_MODE(unsigned int A) { __m128 test_mm_set_ss(float A) { // CHECK-LABEL: test_mm_set_ss - // CHECK: insertelement <4 x float> undef, float {{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float {{.*}}, i32 0 // CHECK: insertelement <4 x float> {{.*}}, float 0.000000e+00, i32 1 // CHECK: insertelement <4 x float> {{.*}}, float 0.000000e+00, i32 2 // CHECK: insertelement <4 x float> {{.*}}, float 0.000000e+00, i32 3 @@ -604,7 +604,7 @@ __m128 test_mm_set_ss(float A) { __m128 test_mm_set1_ps(float A) { // CHECK-LABEL: test_mm_set1_ps - // CHECK: insertelement <4 x float> undef, float {{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float {{.*}}, i32 0 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 1 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 2 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 3 @@ -620,7 +620,7 @@ void test_mm_setcsr(unsigned int A) { __m128 test_mm_setr_ps(float A, float B, float C, float D) { // CHECK-LABEL: test_mm_setr_ps - // CHECK: insertelement <4 x float> undef, float {{.*}}, i32 0 + // CHECK: insertelement <4 x float> poison, float {{.*}}, i32 0 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 1 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 2 // CHECK: insertelement <4 x float> {{.*}}, float {{.*}}, i32 3 diff --git a/clang/test/CodeGen/X86/sse2-builtins.c b/clang/test/CodeGen/X86/sse2-builtins.c index 7165d2791827cfc4d477797bfadf080060170061..44b2e485a5bd85eeead9be1e261676c893f93bc1 100644 --- a/clang/test/CodeGen/X86/sse2-builtins.c +++ b/clang/test/CodeGen/X86/sse2-builtins.c @@ -204,7 +204,7 @@ __m128d test_mm_cmpge_sd(__m128d A, __m128d B) { // CHECK-LABEL: test_mm_cmpge_sd // CHECK: call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i8 2) // CHECK: extractelement <2 x double> %{{.*}}, i32 0 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: extractelement <2 x double> %{{.*}}, i32 1 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_cmpge_sd(A, B); @@ -240,7 +240,7 @@ __m128d test_mm_cmpgt_sd(__m128d A, __m128d B) { // CHECK-LABEL: test_mm_cmpgt_sd // CHECK: call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i8 1) // CHECK: extractelement <2 x double> %{{.*}}, i32 0 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: extractelement <2 x double> %{{.*}}, i32 1 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_cmpgt_sd(A, B); @@ -318,7 +318,7 @@ __m128d test_mm_cmpnge_sd(__m128d A, __m128d B) { // CHECK-LABEL: test_mm_cmpnge_sd // CHECK: call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i8 6) // CHECK: extractelement <2 x double> %{{.*}}, i32 0 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: extractelement <2 x double> %{{.*}}, i32 1 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_cmpnge_sd(A, B); @@ -336,7 +336,7 @@ __m128d test_mm_cmpngt_sd(__m128d A, __m128d B) { // CHECK-LABEL: test_mm_cmpngt_sd // CHECK: call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i8 5) // CHECK: extractelement <2 x double> %{{.*}}, i32 0 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: extractelement <2 x double> %{{.*}}, i32 1 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_cmpngt_sd(A, B); @@ -519,7 +519,7 @@ __m128d test_mm_cvtsi32_sd(__m128d A, int B) { __m128i test_mm_cvtsi32_si128(int A) { // CHECK-LABEL: test_mm_cvtsi32_si128 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 1 // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 2 // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 3 @@ -537,7 +537,7 @@ __m128d test_mm_cvtsi64_sd(__m128d A, long long B) { __m128i test_mm_cvtsi64_si128(long long A) { // CHECK-LABEL: test_mm_cvtsi64_si128 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 0, i32 1 return _mm_cvtsi64_si128(A); } @@ -620,7 +620,7 @@ __m128d test_mm_load_pd(double const* A) { __m128d test_mm_load_pd1(double const* A) { // CHECK-LABEL: test_mm_load_pd1 // CHECK: load double, ptr %{{.*}}, align 8 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_load_pd1(A); } @@ -640,7 +640,7 @@ __m128i test_mm_load_si128(__m128i const* A) { __m128d test_mm_load1_pd(double const* A) { // CHECK-LABEL: test_mm_load1_pd // CHECK: load double, ptr %{{.*}}, align 8 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_load1_pd(A); } @@ -655,7 +655,7 @@ __m128d test_mm_loadh_pd(__m128d x, void* y) { __m128i test_mm_loadl_epi64(__m128i* y) { // CHECK: test_mm_loadl_epi64 // CHECK: load i64, ptr {{.*}}, align 1{{$}} - // CHECK: insertelement <2 x i64> undef, i64 {{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 {{.*}}, i32 0 // CHECK: insertelement <2 x i64> {{.*}}, i64 0, i32 1 return _mm_loadl_epi64(y); } @@ -663,7 +663,7 @@ __m128i test_mm_loadl_epi64(__m128i* y) { __m128d test_mm_loadl_pd(__m128d x, void* y) { // CHECK-LABEL: test_mm_loadl_pd // CHECK: load double, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: extractelement <2 x double> %{{.*}}, i32 1 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_loadl_pd(x, y); @@ -691,7 +691,7 @@ __m128i test_mm_loadu_si128(__m128i const* A) { __m128i test_mm_loadu_si64(void const* A) { // CHECK-LABEL: test_mm_loadu_si64 // CHECK: load i64, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 0, i32 1 return _mm_loadu_si64(A); } @@ -699,7 +699,7 @@ __m128i test_mm_loadu_si64(void const* A) { __m128i test_mm_loadu_si32(void const* A) { // CHECK-LABEL: test_mm_loadu_si32 // CHECK: load i32, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 1 // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 2 // CHECK: insertelement <4 x i32> %{{.*}}, i32 0, i32 3 @@ -709,7 +709,7 @@ __m128i test_mm_loadu_si32(void const* A) { __m128i test_mm_loadu_si16(void const* A) { // CHECK-LABEL: test_mm_loadu_si16 // CHECK: load i16, ptr %{{.*}}, align 1{{$}} - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 0, i32 3 @@ -797,7 +797,7 @@ __m128i test_mm_movpi64_epi64(__m64 A) { // CHECK-LABEL: test_mm_movpi64_epi64 // CHECK: [[CAST:%.*]] = bitcast <1 x i64> %{{.*}} to i64 - // CHECK: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[CAST]], i32 0 + // CHECK: [[INS:%.*]] = insertelement <2 x i64> poison, i64 [[CAST]], i32 0 // CHECK: insertelement <2 x i64> [[INS]], i64 0, i32 1 return _mm_movpi64_epi64(A); } @@ -915,7 +915,7 @@ __m128i test_mm_set_epi8(char A, char B, char C, char D, char I, char J, char K, char L, char M, char N, char O, char P) { // CHECK-LABEL: test_mm_set_epi8 - // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -937,7 +937,7 @@ __m128i test_mm_set_epi8(char A, char B, char C, char D, __m128i test_mm_set_epi16(short A, short B, short C, short D, short E, short F, short G, short H) { // CHECK-LABEL: test_mm_set_epi16 - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -950,7 +950,7 @@ __m128i test_mm_set_epi16(short A, short B, short C, short D, __m128i test_mm_set_epi32(int A, int B, int C, int D) { // CHECK-LABEL: test_mm_set_epi32 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -959,42 +959,42 @@ __m128i test_mm_set_epi32(int A, int B, int C, int D) { __m128i test_mm_set_epi64(__m64 A, __m64 B) { // CHECK-LABEL: test_mm_set_epi64 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 return _mm_set_epi64(A, B); } __m128i test_mm_set_epi64x(long long A, long long B) { // CHECK-LABEL: test_mm_set_epi64x - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 return _mm_set_epi64x(A, B); } __m128d test_mm_set_pd(double A, double B) { // CHECK-LABEL: test_mm_set_pd - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_set_pd(A, B); } __m128d test_mm_set_pd1(double A) { // CHECK-LABEL: test_mm_set_pd1 - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_set_pd1(A); } __m128d test_mm_set_sd(double A) { // CHECK-LABEL: test_mm_set_sd - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double 0.000000e+00, i32 1 return _mm_set_sd(A); } __m128i test_mm_set1_epi8(char A) { // CHECK-LABEL: test_mm_set1_epi8 - // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -1015,7 +1015,7 @@ __m128i test_mm_set1_epi8(char A) { __m128i test_mm_set1_epi16(short A) { // CHECK-LABEL: test_mm_set1_epi16 - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -1028,7 +1028,7 @@ __m128i test_mm_set1_epi16(short A) { __m128i test_mm_set1_epi32(int A) { // CHECK-LABEL: test_mm_set1_epi32 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -1037,21 +1037,21 @@ __m128i test_mm_set1_epi32(int A) { __m128i test_mm_set1_epi64(__m64 A) { // CHECK-LABEL: test_mm_set1_epi64 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 return _mm_set1_epi64(A); } __m128i test_mm_set1_epi64x(long long A) { // CHECK-LABEL: test_mm_set1_epi64x - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 return _mm_set1_epi64x(A); } __m128d test_mm_set1_pd(double A) { // CHECK-LABEL: test_mm_set1_pd - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_set1_pd(A); } @@ -1061,7 +1061,7 @@ __m128i test_mm_setr_epi8(char A, char B, char C, char D, char I, char J, char K, char L, char M, char N, char O, char P) { // CHECK-LABEL: test_mm_setr_epi8 - // CHECK: insertelement <16 x i8> undef, i8 %{{.*}}, i32 0 + // CHECK: insertelement <16 x i8> poison, i8 %{{.*}}, i32 0 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 1 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 2 // CHECK: insertelement <16 x i8> %{{.*}}, i8 %{{.*}}, i32 3 @@ -1083,7 +1083,7 @@ __m128i test_mm_setr_epi8(char A, char B, char C, char D, __m128i test_mm_setr_epi16(short A, short B, short C, short D, short E, short F, short G, short H) { // CHECK-LABEL: test_mm_setr_epi16 - // CHECK: insertelement <8 x i16> undef, i16 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i16> poison, i16 %{{.*}}, i32 0 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 1 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 2 // CHECK: insertelement <8 x i16> %{{.*}}, i16 %{{.*}}, i32 3 @@ -1096,7 +1096,7 @@ __m128i test_mm_setr_epi16(short A, short B, short C, short D, __m128i test_mm_setr_epi32(int A, int B, int C, int D) { // CHECK-LABEL: test_mm_setr_epi32 - // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> poison, i32 %{{.*}}, i32 0 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 1 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 2 // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 3 @@ -1105,14 +1105,14 @@ __m128i test_mm_setr_epi32(int A, int B, int C, int D) { __m128i test_mm_setr_epi64(__m64 A, __m64 B) { // CHECK-LABEL: test_mm_setr_epi64 - // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> poison, i64 %{{.*}}, i32 0 // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 return _mm_setr_epi64(A, B); } __m128d test_mm_setr_pd(double A, double B) { // CHECK-LABEL: test_mm_setr_pd - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_setr_pd(A, B); } diff --git a/clang/test/CodeGen/X86/sse3-builtins.c b/clang/test/CodeGen/X86/sse3-builtins.c index 38f9710f071aec00bf2c53bc61aa070116fbebd1..efc9c31d356d90cbf29458c17fdca2289c59b370 100644 --- a/clang/test/CodeGen/X86/sse3-builtins.c +++ b/clang/test/CodeGen/X86/sse3-builtins.c @@ -51,7 +51,7 @@ __m128i test_mm_lddqu_si128(__m128i const* P) { __m128d test_mm_loaddup_pd(double const* P) { // CHECK-LABEL: test_mm_loaddup_pd // CHECK: load ptr - // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 0 + // CHECK: insertelement <2 x double> poison, double %{{.*}}, i32 0 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 1 return _mm_loaddup_pd(P); } diff --git a/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c b/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c index 0f4d9558080540c9648cc46c8f946d310c7c50ea..877d83c0fa3954c1e0f51a64b7ee1b440e6199c4 100644 --- a/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c +++ b/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c @@ -32,19 +32,19 @@ float32x4_t test_vbfdotq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b){ // CHECK-LABEL: @test_vbfdot_lane_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_144:%.*]] = alloca <4 x bfloat>, align 8 -// CHECK-NEXT: [[__REINT1_144:%.*]] = alloca <2 x float>, align 8 -// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_144]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[__REINT_144]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP3]], <2 x i32> zeroinitializer -// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_144]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x bfloat>, ptr [[__REINT1_144]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <4 x bfloat> [[TMP5]] to <8 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_128:%.*]] = alloca <4 x bfloat>, align 8 +// CHECK-NEXT: [[__REINT1_128:%.*]] = alloca <2 x float>, align 8 +// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_128]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[__REINT_128]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[TMP0]] to <8 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP2]], <2 x float> [[TMP2]], <2 x i32> zeroinitializer +// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_128]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x bfloat>, ptr [[__REINT1_128]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x bfloat> [[TMP3]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <2 x float> [[VBFDOT3_I]] // float32x2_t test_vbfdot_lane_f32(float32x2_t r, bfloat16x4_t a, bfloat16x4_t b){ @@ -53,19 +53,19 @@ float32x2_t test_vbfdot_lane_f32(float32x2_t r, bfloat16x4_t a, bfloat16x4_t b){ // CHECK-LABEL: @test_vbfdotq_laneq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_146:%.*]] = alloca <8 x bfloat>, align 16 -// CHECK-NEXT: [[__REINT1_146:%.*]] = alloca <4 x float>, align 16 -// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_146]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[__REINT_146]], align 16 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP3]], <4 x float> [[TMP3]], <4 x i32> -// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_146]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x bfloat>, ptr [[__REINT1_146]], align 16 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x bfloat> [[TMP5]] to <16 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_130:%.*]] = alloca <8 x bfloat>, align 16 +// CHECK-NEXT: [[__REINT1_130:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_130]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[__REINT_130]], align 16 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP2]], <4 x i32> +// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_130]], align 16 +// CHECK-NEXT: [[TMP3:%.*]] = load <8 x bfloat>, ptr [[__REINT1_130]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x bfloat> [[TMP3]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <4 x float> [[VBFDOT3_I]] // float32x4_t test_vbfdotq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { @@ -74,19 +74,19 @@ float32x4_t test_vbfdotq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b // CHECK-LABEL: @test_vbfdot_laneq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_148:%.*]] = alloca <8 x bfloat>, align 16 -// CHECK-NEXT: [[__REINT1_148:%.*]] = alloca <2 x float>, align 8 -// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_148]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[__REINT_148]], align 16 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP3]], <4 x float> [[TMP3]], <2 x i32> -// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_148]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x bfloat>, ptr [[__REINT1_148]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <4 x bfloat> [[TMP5]] to <8 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_132:%.*]] = alloca <8 x bfloat>, align 16 +// CHECK-NEXT: [[__REINT1_132:%.*]] = alloca <2 x float>, align 8 +// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_132]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[__REINT_132]], align 16 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP2]], <2 x i32> +// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_132]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x bfloat>, ptr [[__REINT1_132]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x bfloat> [[TMP3]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <2 x float> [[VBFDOT3_I]] // float32x2_t test_vbfdot_laneq_f32(float32x2_t r, bfloat16x4_t a, bfloat16x8_t b) { @@ -95,19 +95,19 @@ float32x2_t test_vbfdot_laneq_f32(float32x2_t r, bfloat16x4_t a, bfloat16x8_t b) // CHECK-LABEL: @test_vbfdotq_lane_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_142:%.*]] = alloca <4 x bfloat>, align 8 -// CHECK-NEXT: [[__REINT1_142:%.*]] = alloca <4 x float>, align 16 -// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_142]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[__REINT_142]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP3]], <4 x i32> zeroinitializer -// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_142]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x bfloat>, ptr [[__REINT1_142]], align 16 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x bfloat> [[TMP5]] to <16 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_126:%.*]] = alloca <4 x bfloat>, align 8 +// CHECK-NEXT: [[__REINT1_126:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_126]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[__REINT_126]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[TMP0]] to <8 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP2]], <2 x float> [[TMP2]], <4 x i32> zeroinitializer +// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_126]], align 16 +// CHECK-NEXT: [[TMP3:%.*]] = load <8 x bfloat>, ptr [[__REINT1_126]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x bfloat> [[TMP3]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <4 x float> [[VBFDOT3_I]] // float32x4_t test_vbfdotq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { @@ -119,9 +119,9 @@ float32x4_t test_vbfdotq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VBFMMLAQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmmla(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) -// CHECK-NEXT: [[VBFMMLAQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMMLAQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMMLAQ_V3_I]] +// CHECK-NEXT: [[VBFMMLAQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmmla(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) +// CHECK-NEXT: [[VBFMMLAQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMMLAQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMMLAQ_F323_I]] // float32x4_t test_vbfmmlaq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmmlaq_f32(r, a, b); @@ -132,9 +132,9 @@ float32x4_t test_vbfmmlaq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALBQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) -// CHECK-NEXT: [[VBFMLALBQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_V3_I]] +// CHECK-NEXT: [[VBFMLALBQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) +// CHECK-NEXT: [[VBFMLALBQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_F323_I]] // float32x4_t test_vbfmlalbq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlalbq_f32(r, a, b); @@ -145,9 +145,9 @@ float32x4_t test_vbfmlalbq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALTQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) -// CHECK-NEXT: [[VBFMLALTQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_V3_I]] +// CHECK-NEXT: [[VBFMLALTQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) +// CHECK-NEXT: [[VBFMLALTQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_F323_I]] // float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlaltq_f32(r, a, b); @@ -156,7 +156,7 @@ float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-LABEL: @test_vbfmlalbq_lane_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[B:%.*]], i32 0 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGET_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGET_LANE]], i32 0 // CHECK-NEXT: [[VGET_LANE3:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGET_LANE3]], i32 1 // CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 @@ -174,9 +174,9 @@ float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALBQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALBQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_V3_I]] +// CHECK-NEXT: [[VBFMLALBQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALBQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_F323_I]] // float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { return vbfmlalbq_lane_f32(r, a, b, 0); @@ -185,7 +185,7 @@ float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-LABEL: @test_vbfmlalbq_laneq_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 3 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGETQ_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGETQ_LANE]], i32 0 // CHECK-NEXT: [[VGETQ_LANE3:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGETQ_LANE3]], i32 1 // CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 @@ -203,9 +203,9 @@ float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALBQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALBQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_V3_I]] +// CHECK-NEXT: [[VBFMLALBQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALBQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_F323_I]] // float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlalbq_laneq_f32(r, a, b, 3); @@ -214,7 +214,7 @@ float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t // CHECK-LABEL: @test_vbfmlaltq_lane_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[B:%.*]], i32 0 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGET_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGET_LANE]], i32 0 // CHECK-NEXT: [[VGET_LANE3:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGET_LANE3]], i32 1 // CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 @@ -232,9 +232,9 @@ float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALTQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALTQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_V3_I]] +// CHECK-NEXT: [[VBFMLALTQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALTQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_F323_I]] // float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { return vbfmlaltq_lane_f32(r, a, b, 0); @@ -243,7 +243,7 @@ float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-LABEL: @test_vbfmlaltq_laneq_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 3 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGETQ_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGETQ_LANE]], i32 0 // CHECK-NEXT: [[VGETQ_LANE3:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGETQ_LANE3]], i32 1 // CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 @@ -261,9 +261,9 @@ float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALTQ_V3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALTQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_V3_I]] +// CHECK-NEXT: [[VBFMLALTQ_F323_I:%.*]] = call <4 x float> @llvm.aarch64.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALTQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_F323_I]] // float32x4_t test_vbfmlaltq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlaltq_laneq_f32(r, a, b, 3); diff --git a/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c b/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c index e07d93f7f0182f2de44ff16786d42365b305d2c9..9da2cd5af32212aed0684c535b6c4da4be855c1f 100644 --- a/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c +++ b/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c @@ -17,7 +17,7 @@ bfloat16x4_t test_vcreate_bf16(uint64_t a) { // CHECK-LABEL: @test_vdup_n_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x bfloat> undef, bfloat [[V:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x bfloat> poison, bfloat [[V:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x bfloat> [[VECINIT_I]], bfloat [[V]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x bfloat> [[VECINIT1_I]], bfloat [[V]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x bfloat> [[VECINIT2_I]], bfloat [[V]], i32 3 @@ -29,7 +29,7 @@ bfloat16x4_t test_vdup_n_bf16(bfloat16_t v) { // CHECK-LABEL: @test_vdupq_n_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x bfloat> undef, bfloat [[V:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x bfloat> poison, bfloat [[V:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x bfloat> [[VECINIT_I]], bfloat [[V]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x bfloat> [[VECINIT1_I]], bfloat [[V]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x bfloat> [[VECINIT2_I]], bfloat [[V]], i32 3 diff --git a/clang/test/CodeGen/aarch64-branch-protection-attr.c b/clang/test/CodeGen/aarch64-branch-protection-attr.c index 3c2714e2feda240d30ea33fe5ba43cfc947e6be7..8ab3e17ade426466dbac8d6e8cfca4ca226a8dd1 100644 --- a/clang/test/CodeGen/aarch64-branch-protection-attr.c +++ b/clang/test/CodeGen/aarch64-branch-protection-attr.c @@ -46,6 +46,24 @@ __attribute__ ((target("branch-protection=pac-ret+leaf+bti"))) void btileaf() {} // CHECK: define{{.*}} void @btileaf() #[[#BTIPACLEAF:]] + +__attribute__ ((target("branch-protection=pac-ret+pc"))) +void pauthlr() {} +// CHECK: define{{.*}} void @pauthlr() #[[#PAUTHLR:]] + +__attribute__ ((target("branch-protection=pac-ret+pc+b-key"))) +void pauthlr_bkey() {} +// CHECK: define{{.*}} void @pauthlr_bkey() #[[#PAUTHLR_BKEY:]] + +__attribute__ ((target("branch-protection=pac-ret+pc+leaf"))) +void pauthlr_leaf() {} +// CHECK: define{{.*}} void @pauthlr_leaf() #[[#PAUTHLR_LEAF:]] + +__attribute__ ((target("branch-protection=pac-ret+pc+bti"))) +void pauthlr_bti() {} +// CHECK: define{{.*}} void @pauthlr_bti() #[[#PAUTHLR_BTI:]] + + // CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="none" // CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" @@ -61,3 +79,13 @@ void btileaf() {} // CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="b_key" // CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" + + +// CHECK-DAG: attributes #[[#PAUTHLR]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" + +// CHECK-DAG: attributes #[[#PAUTHLR_BKEY]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key" + +// CHECK-DAG: attributes #[[#PAUTHLR_LEAF]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key" + +// CHECK-DAG: attributes #[[#PAUTHLR_BTI]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="true" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" + diff --git a/clang/test/CodeGen/aarch64-neon-2velem.c b/clang/test/CodeGen/aarch64-neon-2velem.c index 786c8149f38c53d073079e5f56450a327277b770..75bdeb92fd9ca6c6ff3d6e22859ed24a8b36ee44 100644 --- a/clang/test/CodeGen/aarch64-neon-2velem.c +++ b/clang/test/CodeGen/aarch64-neon-2velem.c @@ -3736,7 +3736,7 @@ float64x2_t test_vmulxq_laneq_f64_0(float64x2_t a, float64x2_t v) { // CHECK-LABEL: @test_vmull_high_n_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[A:%.*]], <8 x i16> [[A]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -3752,7 +3752,7 @@ int32x4_t test_vmull_high_n_s16(int16x8_t a, int16_t b) { // CHECK-LABEL: @test_vmull_high_n_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[A]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3766,7 +3766,7 @@ int64x2_t test_vmull_high_n_s32(int32x4_t a, int32_t b) { // CHECK-LABEL: @test_vmull_high_n_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[A:%.*]], <8 x i16> [[A]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -3782,7 +3782,7 @@ uint32x4_t test_vmull_high_n_u16(uint16x8_t a, uint16_t b) { // CHECK-LABEL: @test_vmull_high_n_u32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[A]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3796,7 +3796,7 @@ uint64x2_t test_vmull_high_n_u32(uint32x4_t a, uint32_t b) { // CHECK-LABEL: @test_vqdmull_high_n_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[A:%.*]], <8 x i16> [[A]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -3813,7 +3813,7 @@ int32x4_t test_vqdmull_high_n_s16(int16x8_t a, int16_t b) { // CHECK-LABEL: @test_vqdmull_high_n_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[A]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3828,7 +3828,7 @@ int64x2_t test_vqdmull_high_n_s32(int32x4_t a, int32_t b) { // CHECK-LABEL: @test_vmlal_high_n_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B:%.*]], <8 x i16> [[B]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -3845,7 +3845,7 @@ int32x4_t test_vmlal_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) { // CHECK-LABEL: @test_vmlal_high_n_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> [[B]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3860,7 +3860,7 @@ int64x2_t test_vmlal_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) { // CHECK-LABEL: @test_vmlal_high_n_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B:%.*]], <8 x i16> [[B]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -3877,7 +3877,7 @@ uint32x4_t test_vmlal_high_n_u16(uint32x4_t a, uint16x8_t b, uint16_t c) { // CHECK-LABEL: @test_vmlal_high_n_u32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> [[B]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3892,7 +3892,7 @@ uint64x2_t test_vmlal_high_n_u32(uint64x2_t a, uint32x4_t b, uint32_t c) { // CHECK-LABEL: @test_vqdmlal_high_n_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B:%.*]], <8 x i16> [[B]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -3910,7 +3910,7 @@ int32x4_t test_vqdmlal_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) { // CHECK-LABEL: @test_vqdmlal_high_n_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> [[B]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> @@ -3926,7 +3926,7 @@ int64x2_t test_vqdmlal_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) { // CHECK-LABEL: @test_vmlsl_high_n_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B:%.*]], <8 x i16> [[B]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -3943,7 +3943,7 @@ int32x4_t test_vmlsl_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) { // CHECK-LABEL: @test_vmlsl_high_n_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> [[B]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3958,7 +3958,7 @@ int64x2_t test_vmlsl_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) { // CHECK-LABEL: @test_vmlsl_high_n_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B:%.*]], <8 x i16> [[B]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -3975,7 +3975,7 @@ uint32x4_t test_vmlsl_high_n_u16(uint32x4_t a, uint16x8_t b, uint16_t c) { // CHECK-LABEL: @test_vmlsl_high_n_u32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> [[B]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -3990,7 +3990,7 @@ uint64x2_t test_vmlsl_high_n_u32(uint64x2_t a, uint32x4_t b, uint32_t c) { // CHECK-LABEL: @test_vqdmlsl_high_n_s16( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B:%.*]], <8 x i16> [[B]], <4 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4008,7 +4008,7 @@ int32x4_t test_vqdmlsl_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) { // CHECK-LABEL: @test_vqdmlsl_high_n_s32( // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> [[B]], <2 x i32> -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8> @@ -4023,7 +4023,7 @@ int64x2_t test_vqdmlsl_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) { // CHECK-LABEL: @test_vmul_n_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float [[B]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = fmul <2 x float> [[A:%.*]], [[VECINIT1_I]] // CHECK-NEXT: ret <2 x float> [[MUL_I]] @@ -4034,7 +4034,7 @@ float32x2_t test_vmul_n_f32(float32x2_t a, float32_t b) { // CHECK-LABEL: @test_vmulq_n_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[B]], i32 3 @@ -4047,7 +4047,7 @@ float32x4_t test_vmulq_n_f32(float32x4_t a, float32_t b) { // CHECK-LABEL: @test_vmulq_n_f64( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[B]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = fmul <2 x double> [[A:%.*]], [[VECINIT1_I]] // CHECK-NEXT: ret <2 x double> [[MUL_I]] @@ -4058,7 +4058,7 @@ float64x2_t test_vmulq_n_f64(float64x2_t a, float64_t b) { // CHECK-LABEL: @test_vfma_n_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float [[N:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float [[N:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float [[N]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[B:%.*]] to <8 x i8> @@ -4072,7 +4072,7 @@ float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { // CHECK-LABEL: @test_vfma_n_f64( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <1 x double> undef, double [[N:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <1 x double> poison, double [[N:%.*]], i32 0 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x double> [[B:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <1 x double> [[VECINIT_I]] to <8 x i8> @@ -4085,7 +4085,7 @@ float64x1_t test_vfma_n_f64(float64x1_t a, float64x1_t b, float64_t n) { // CHECK-LABEL: @test_vfmaq_n_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[N:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[N:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[N]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[N]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[N]], i32 3 @@ -4102,7 +4102,7 @@ float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) { // CHECK-LABEL: @test_vfms_n_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <2 x float> [[B:%.*]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float [[N:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float [[N:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float [[N]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[FNEG_I]] to <8 x i8> @@ -4117,7 +4117,7 @@ float32x2_t test_vfms_n_f32(float32x2_t a, float32x2_t b, float32_t n) { // CHECK-LABEL: @test_vfms_n_f64( // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <1 x double> [[B:%.*]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <1 x double> undef, double [[N:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <1 x double> poison, double [[N:%.*]], i32 0 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x double> [[FNEG_I]] to <8 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <1 x double> [[VECINIT_I]] to <8 x i8> @@ -4131,7 +4131,7 @@ float64x1_t test_vfms_n_f64(float64x1_t a, float64x1_t b, float64_t n) { // CHECK-LABEL: @test_vfmsq_n_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <4 x float> [[B:%.*]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[N:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[N:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[N]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[N]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[N]], i32 3 @@ -4147,7 +4147,7 @@ float32x4_t test_vfmsq_n_f32(float32x4_t a, float32x4_t b, float32_t n) { // CHECK-LABEL: @test_vmul_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4160,7 +4160,7 @@ int16x4_t test_vmul_n_s16(int16x4_t a, int16_t b) { // CHECK-LABEL: @test_vmulq_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4177,7 +4177,7 @@ int16x8_t test_vmulq_n_s16(int16x8_t a, int16_t b) { // CHECK-LABEL: @test_vmul_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = mul <2 x i32> [[A:%.*]], [[VECINIT1_I]] // CHECK-NEXT: ret <2 x i32> [[MUL_I]] @@ -4188,7 +4188,7 @@ int32x2_t test_vmul_n_s32(int32x2_t a, int32_t b) { // CHECK-LABEL: @test_vmulq_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[B]], i32 3 @@ -4201,7 +4201,7 @@ int32x4_t test_vmulq_n_s32(int32x4_t a, int32_t b) { // CHECK-LABEL: @test_vmul_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4214,7 +4214,7 @@ uint16x4_t test_vmul_n_u16(uint16x4_t a, uint16_t b) { // CHECK-LABEL: @test_vmulq_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4231,7 +4231,7 @@ uint16x8_t test_vmulq_n_u16(uint16x8_t a, uint16_t b) { // CHECK-LABEL: @test_vmul_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = mul <2 x i32> [[A:%.*]], [[VECINIT1_I]] // CHECK-NEXT: ret <2 x i32> [[MUL_I]] @@ -4242,7 +4242,7 @@ uint32x2_t test_vmul_n_u32(uint32x2_t a, uint32_t b) { // CHECK-LABEL: @test_vmulq_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[B]], i32 3 @@ -4255,7 +4255,7 @@ uint32x4_t test_vmulq_n_u32(uint32x4_t a, uint32_t b) { // CHECK-LABEL: @test_vmull_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4270,7 +4270,7 @@ int32x4_t test_vmull_n_s16(int16x4_t a, int16_t b) { // CHECK-LABEL: @test_vmull_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4283,7 +4283,7 @@ int64x2_t test_vmull_n_s32(int32x2_t a, int32_t b) { // CHECK-LABEL: @test_vmull_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4298,7 +4298,7 @@ uint32x4_t test_vmull_n_u16(uint16x4_t a, uint16_t b) { // CHECK-LABEL: @test_vmull_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4311,7 +4311,7 @@ uint64x2_t test_vmull_n_u32(uint32x2_t a, uint32_t b) { // CHECK-LABEL: @test_vqdmull_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4327,7 +4327,7 @@ int32x4_t test_vqdmull_n_s16(int16x4_t a, int16_t b) { // CHECK-LABEL: @test_vqdmull_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4341,7 +4341,7 @@ int64x2_t test_vqdmull_n_s32(int32x2_t a, int32_t b) { // CHECK-LABEL: @test_vqdmulh_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4357,7 +4357,7 @@ int16x4_t test_vqdmulh_n_s16(int16x4_t a, int16_t b) { // CHECK-LABEL: @test_vqdmulhq_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4377,7 +4377,7 @@ int16x8_t test_vqdmulhq_n_s16(int16x8_t a, int16_t b) { // CHECK-LABEL: @test_vqdmulh_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4391,7 +4391,7 @@ int32x2_t test_vqdmulh_n_s32(int32x2_t a, int32_t b) { // CHECK-LABEL: @test_vqdmulhq_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[B]], i32 3 @@ -4407,7 +4407,7 @@ int32x4_t test_vqdmulhq_n_s32(int32x4_t a, int32_t b) { // CHECK-LABEL: @test_vqrdmulh_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4423,7 +4423,7 @@ int16x4_t test_vqrdmulh_n_s16(int16x4_t a, int16_t b) { // CHECK-LABEL: @test_vqrdmulhq_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[B]], i32 3 @@ -4443,7 +4443,7 @@ int16x8_t test_vqrdmulhq_n_s16(int16x8_t a, int16_t b) { // CHECK-LABEL: @test_vqrdmulh_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[A:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4457,7 +4457,7 @@ int32x2_t test_vqrdmulh_n_s32(int32x2_t a, int32_t b) { // CHECK-LABEL: @test_vqrdmulhq_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[B:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[B:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[B]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[B]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[B]], i32 3 @@ -4473,7 +4473,7 @@ int32x4_t test_vqrdmulhq_n_s32(int32x4_t a, int32_t b) { // CHECK-LABEL: @test_vmla_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4487,7 +4487,7 @@ int16x4_t test_vmla_n_s16(int16x4_t a, int16x4_t b, int16_t c) { // CHECK-LABEL: @test_vmlaq_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4505,7 +4505,7 @@ int16x8_t test_vmlaq_n_s16(int16x8_t a, int16x8_t b, int16_t c) { // CHECK-LABEL: @test_vmla_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = mul <2 x i32> [[B:%.*]], [[VECINIT1_I]] // CHECK-NEXT: [[ADD_I:%.*]] = add <2 x i32> [[A:%.*]], [[MUL_I]] @@ -4517,7 +4517,7 @@ int32x2_t test_vmla_n_s32(int32x2_t a, int32x2_t b, int32_t c) { // CHECK-LABEL: @test_vmlaq_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[C]], i32 3 @@ -4531,7 +4531,7 @@ int32x4_t test_vmlaq_n_s32(int32x4_t a, int32x4_t b, int32_t c) { // CHECK-LABEL: @test_vmla_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4545,7 +4545,7 @@ uint16x4_t test_vmla_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) { // CHECK-LABEL: @test_vmlaq_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4563,7 +4563,7 @@ uint16x8_t test_vmlaq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) { // CHECK-LABEL: @test_vmla_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = mul <2 x i32> [[B:%.*]], [[VECINIT1_I]] // CHECK-NEXT: [[ADD_I:%.*]] = add <2 x i32> [[A:%.*]], [[MUL_I]] @@ -4575,7 +4575,7 @@ uint32x2_t test_vmla_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) { // CHECK-LABEL: @test_vmlaq_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[C]], i32 3 @@ -4589,7 +4589,7 @@ uint32x4_t test_vmlaq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) { // CHECK-LABEL: @test_vmlal_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4605,7 +4605,7 @@ int32x4_t test_vmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) { // CHECK-LABEL: @test_vmlal_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[B:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4619,7 +4619,7 @@ int64x2_t test_vmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) { // CHECK-LABEL: @test_vmlal_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4635,7 +4635,7 @@ uint32x4_t test_vmlal_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) { // CHECK-LABEL: @test_vmlal_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[B:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4649,7 +4649,7 @@ uint64x2_t test_vmlal_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) { // CHECK-LABEL: @test_vqdmlal_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4666,7 +4666,7 @@ int32x4_t test_vqdmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) { // CHECK-LABEL: @test_vqdmlal_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B:%.*]] to <8 x i8> @@ -4681,7 +4681,7 @@ int64x2_t test_vqdmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) { // CHECK-LABEL: @test_vmls_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4695,7 +4695,7 @@ int16x4_t test_vmls_n_s16(int16x4_t a, int16x4_t b, int16_t c) { // CHECK-LABEL: @test_vmlsq_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4713,7 +4713,7 @@ int16x8_t test_vmlsq_n_s16(int16x8_t a, int16x8_t b, int16_t c) { // CHECK-LABEL: @test_vmls_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = mul <2 x i32> [[B:%.*]], [[VECINIT1_I]] // CHECK-NEXT: [[SUB_I:%.*]] = sub <2 x i32> [[A:%.*]], [[MUL_I]] @@ -4725,7 +4725,7 @@ int32x2_t test_vmls_n_s32(int32x2_t a, int32x2_t b, int32_t c) { // CHECK-LABEL: @test_vmlsq_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[C]], i32 3 @@ -4739,7 +4739,7 @@ int32x4_t test_vmlsq_n_s32(int32x4_t a, int32x4_t b, int32_t c) { // CHECK-LABEL: @test_vmls_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4753,7 +4753,7 @@ uint16x4_t test_vmls_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) { // CHECK-LABEL: @test_vmlsq_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4771,7 +4771,7 @@ uint16x8_t test_vmlsq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) { // CHECK-LABEL: @test_vmls_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = mul <2 x i32> [[B:%.*]], [[VECINIT1_I]] // CHECK-NEXT: [[SUB_I:%.*]] = sub <2 x i32> [[A:%.*]], [[MUL_I]] @@ -4783,7 +4783,7 @@ uint32x2_t test_vmls_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) { // CHECK-LABEL: @test_vmlsq_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[C]], i32 3 @@ -4797,7 +4797,7 @@ uint32x4_t test_vmlsq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) { // CHECK-LABEL: @test_vmlsl_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4813,7 +4813,7 @@ int32x4_t test_vmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) { // CHECK-LABEL: @test_vmlsl_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[B:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4827,7 +4827,7 @@ int64x2_t test_vmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) { // CHECK-LABEL: @test_vmlsl_n_u16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4843,7 +4843,7 @@ uint32x4_t test_vmlsl_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) { // CHECK-LABEL: @test_vmlsl_n_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[B:%.*]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -4857,7 +4857,7 @@ uint64x2_t test_vmlsl_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) { // CHECK-LABEL: @test_vqdmlsl_n_s16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 [[C]], i32 3 @@ -4874,7 +4874,7 @@ int32x4_t test_vqdmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) { // CHECK-LABEL: @test_vqdmlsl_n_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 [[C:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 [[C:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B:%.*]] to <8 x i8> diff --git a/clang/test/CodeGen/aarch64-neon-fma.c b/clang/test/CodeGen/aarch64-neon-fma.c index acc8d050d5ca217bf8f1dadd3b375e45544571ae..074e22d98fcb60768d36ceb47c254aaeec5ae7df 100644 --- a/clang/test/CodeGen/aarch64-neon-fma.c +++ b/clang/test/CodeGen/aarch64-neon-fma.c @@ -8,7 +8,7 @@ // CHECK-LABEL: define {{[^@]+}}@test_vmla_n_f32 // CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float [[C]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float [[C]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float [[C]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = fmul <2 x float> [[B]], [[VECINIT1_I]] // CHECK-NEXT: [[ADD_I:%.*]] = fadd <2 x float> [[A]], [[MUL_I]] @@ -19,9 +19,9 @@ float32x2_t test_vmla_n_f32(float32x2_t a, float32x2_t b, float32_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlaq_n_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[C]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[C]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[C]], i32 3 @@ -34,9 +34,9 @@ float32x4_t test_vmlaq_n_f32(float32x4_t a, float32x4_t b, float32_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlsq_n_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[C]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[C]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[C]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[C]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[C]], i32 3 @@ -51,7 +51,7 @@ float32x4_t test_vmlsq_n_f32(float32x4_t a, float32x4_t b, float32_t c) { // CHECK-LABEL: define {{[^@]+}}@test_vmls_n_f32 // CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float [[C]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float [[C]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float [[C]], i32 1 // CHECK-NEXT: [[MUL_I:%.*]] = fmul <2 x float> [[B]], [[VECINIT1_I]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub <2 x float> [[A]], [[MUL_I]] @@ -76,7 +76,7 @@ float32x2_t test_vmla_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlaq_lane_f32_0 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x float> @@ -90,7 +90,7 @@ float32x4_t test_vmlaq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmla_laneq_f32_0 -// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -104,7 +104,7 @@ float32x2_t test_vmla_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlaq_laneq_f32_0 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -132,7 +132,7 @@ float32x2_t test_vmls_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlsq_lane_f32_0 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x float> @@ -146,7 +146,7 @@ float32x4_t test_vmlsq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmls_laneq_f32_0 -// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -160,7 +160,7 @@ float32x2_t test_vmls_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlsq_laneq_f32_0 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -188,7 +188,7 @@ float32x2_t test_vmla_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlaq_lane_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x float> @@ -202,7 +202,7 @@ float32x4_t test_vmlaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmla_laneq_f32 -// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -216,7 +216,7 @@ float32x2_t test_vmla_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlaq_laneq_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -244,7 +244,7 @@ float32x2_t test_vmls_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlsq_lane_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <2 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x float> @@ -257,7 +257,7 @@ float32x4_t test_vmlsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) { return vmlsq_lane_f32(a, b, v, 1); } // CHECK-LABEL: define {{[^@]+}}@test_vmls_laneq_f32 -// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -271,7 +271,7 @@ float32x2_t test_vmls_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vmlsq_laneq_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x float> @@ -285,9 +285,9 @@ float32x4_t test_vmlsq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_n_f64 -// CHECK-SAME: (<2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]], double noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]], double noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double [[C]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[C]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[B]] to <16 x i8> @@ -300,10 +300,10 @@ float64x2_t test_vfmaq_n_f64(float64x2_t a, float64x2_t b, float64_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_n_f64 -// CHECK-SAME: (<2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]], double noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]], double noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <2 x double> [[B]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double [[C]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[C]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[C]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[FNEG_I]] to <16 x i8> diff --git a/clang/test/CodeGen/aarch64-neon-fp16fml.c b/clang/test/CodeGen/aarch64-neon-fp16fml.c index a7c6d822cd88345fe02a12b22dc5d2a0968e9105..976045d6e79f3dad2b8556756ebeb3c0eec59708 100644 --- a/clang/test/CodeGen/aarch64-neon-fp16fml.c +++ b/clang/test/CodeGen/aarch64-neon-fp16fml.c @@ -110,41 +110,41 @@ float32x4_t test_vfmlslq_high_f16(float32x4_t a, float16x8_t b, float16x8_t c) { // CHECK-LABEL: @test_vfmlal_lane_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLAL_LOW3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLAL_LOW3_I]] // @@ -154,41 +154,41 @@ float32x2_t test_vfmlal_lane_low_f16(float32x2_t a, float16x4_t b, float16x4_t c // CHECK-LABEL: @test_vfmlal_lane_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLAL_HIGH3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLAL_HIGH3_I]] // @@ -198,73 +198,73 @@ float32x2_t test_vfmlal_lane_high_f16(float32x2_t a, float16x4_t b, float16x4_t // CHECK-LABEL: @test_vfmlalq_lane_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85134:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85135:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85144:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85145:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85154:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85155:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85164:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85165:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[TMP17:%.*]] = load <4 x i16>, ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP17]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[TMP21:%.*]] = load <4 x i16>, ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP21]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[TMP25:%.*]] = load <4 x i16>, ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP25]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[TMP29:%.*]] = load <4 x i16>, ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP29]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84734:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84735:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84744:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84745:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84754:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84755:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84764:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84765:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x i16>, ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP8]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x i16>, ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP10]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load <4 x i16>, ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP12]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = load <4 x i16>, ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP14]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLAL_LOW3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLAL_LOW3_I]] // @@ -274,73 +274,73 @@ float32x4_t test_vfmlalq_lane_low_f16(float32x4_t a, float16x8_t b, float16x4_t // CHECK-LABEL: @test_vfmlalq_lane_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85134:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85135:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85144:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85145:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85154:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85155:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85164:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85165:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[TMP17:%.*]] = load <4 x i16>, ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP17]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[TMP21:%.*]] = load <4 x i16>, ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP21]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[TMP25:%.*]] = load <4 x i16>, ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP25]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[TMP29:%.*]] = load <4 x i16>, ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP29]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84734:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84735:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84744:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84745:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84754:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84755:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84764:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84765:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x i16>, ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP8]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x i16>, ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP10]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load <4 x i16>, ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP12]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = load <4 x i16>, ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP14]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLAL_HIGH3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLAL_HIGH3_I]] // @@ -350,41 +350,41 @@ float32x4_t test_vfmlalq_lane_high_f16(float32x4_t a, float16x8_t b, float16x4_t // CHECK-LABEL: @test_vfmlal_laneq_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLAL_LOW3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLAL_LOW3_I]] // @@ -394,41 +394,41 @@ float32x2_t test_vfmlal_laneq_low_f16(float32x2_t a, float16x4_t b, float16x8_t // CHECK-LABEL: @test_vfmlal_laneq_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLAL_HIGH3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLAL_HIGH3_I]] // @@ -438,73 +438,73 @@ float32x2_t test_vfmlal_laneq_high_f16(float32x2_t a, float16x4_t b, float16x8_t // CHECK-LABEL: @test_vfmlalq_laneq_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85434:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85435:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85444:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85445:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85454:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85455:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85464:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85465:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[TMP17:%.*]] = load <8 x i16>, ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP17]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[TMP21:%.*]] = load <8 x i16>, ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP21]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[TMP25:%.*]] = load <8 x i16>, ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP25]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[TMP29:%.*]] = load <8 x i16>, ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP29]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85034:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85035:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85044:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85045:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85054:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85055:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85064:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85065:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[TMP8:%.*]] = load <8 x i16>, ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP8]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[TMP10:%.*]] = load <8 x i16>, ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP10]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[TMP12:%.*]] = load <8 x i16>, ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP12]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[TMP14:%.*]] = load <8 x i16>, ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP14]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLAL_LOW3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLAL_LOW3_I]] // @@ -514,73 +514,73 @@ float32x4_t test_vfmlalq_laneq_low_f16(float32x4_t a, float16x8_t b, float16x8_t // CHECK-LABEL: @test_vfmlalq_laneq_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85434:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85435:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85444:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85445:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85454:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85455:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85464:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85465:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[TMP17:%.*]] = load <8 x i16>, ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP17]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[TMP21:%.*]] = load <8 x i16>, ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP21]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[TMP25:%.*]] = load <8 x i16>, ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP25]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[TMP29:%.*]] = load <8 x i16>, ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP29]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85034:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85035:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85044:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85045:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85054:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85055:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85064:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85065:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[TMP8:%.*]] = load <8 x i16>, ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP8]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[TMP10:%.*]] = load <8 x i16>, ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP10]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[TMP12:%.*]] = load <8 x i16>, ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP12]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[TMP14:%.*]] = load <8 x i16>, ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP14]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLAL_HIGH3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLAL_HIGH3_I]] // @@ -590,41 +590,41 @@ float32x4_t test_vfmlalq_laneq_high_f16(float32x4_t a, float16x8_t b, float16x8_ // CHECK-LABEL: @test_vfmlsl_lane_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 0 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 0 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLSL_LOW3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLSL_LOW3_I]] // @@ -634,41 +634,41 @@ float32x2_t test_vfmlsl_lane_low_f16(float32x2_t a, float16x4_t b, float16x4_t c // CHECK-LABEL: @test_vfmlsl_lane_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 1 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 1 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLSL_HIGH3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLSL_HIGH3_I]] // @@ -678,73 +678,73 @@ float32x2_t test_vfmlsl_lane_high_f16(float32x2_t a, float16x4_t b, float16x4_t // CHECK-LABEL: @test_vfmlslq_lane_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85134:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85135:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85144:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85145:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85154:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85155:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85164:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85165:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[TMP17:%.*]] = load <4 x i16>, ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP17]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[TMP21:%.*]] = load <4 x i16>, ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP21]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[TMP25:%.*]] = load <4 x i16>, ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP25]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[TMP29:%.*]] = load <4 x i16>, ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP29]], i32 2 -// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84734:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84735:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84744:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84745:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84754:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84755:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84764:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84765:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x i16>, ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP8]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x i16>, ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP10]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load <4 x i16>, ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP12]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = load <4 x i16>, ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP14]], i32 2 +// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLSL_LOW3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLSL_LOW3_I]] // @@ -754,73 +754,73 @@ float32x4_t test_vfmlslq_lane_low_f16(float32x4_t a, float16x8_t b, float16x4_t // CHECK-LABEL: @test_vfmlslq_lane_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_851:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_851:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8514:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_8515:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85114:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85115:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85124:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85125:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85134:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85135:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85144:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85145:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85154:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85155:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85164:%.*]] = alloca <4 x half>, align 8 -// CHECK-NEXT: [[__REINT1_85165:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i16>, ptr [[__REINT_851]], align 8 -// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP1]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_851]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr [[__REINT_8514]], align 8 -// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8515]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = load <4 x i16>, ptr [[__REINT_85114]], align 8 -// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP9]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85115]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[TMP13:%.*]] = load <4 x i16>, ptr [[__REINT_85124]], align 8 -// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP13]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85125]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[TMP17:%.*]] = load <4 x i16>, ptr [[__REINT_85134]], align 8 -// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP17]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85135]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[TMP21:%.*]] = load <4 x i16>, ptr [[__REINT_85144]], align 8 -// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP21]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85145]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[TMP25:%.*]] = load <4 x i16>, ptr [[__REINT_85154]], align 8 -// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP25]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85155]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[TMP29:%.*]] = load <4 x i16>, ptr [[__REINT_85164]], align 8 -// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP29]], i32 3 -// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85165]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_847:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_847:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8474:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_8475:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84714:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84715:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84724:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84725:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84734:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84735:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84744:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84745:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84754:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84755:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_84764:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[__REINT1_84765:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <4 x half> [[C:%.*]], ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[__REINT_847]], align 8 +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x i16> [[TMP0]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE]], ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_847]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[__REINT_8474]], align 8 +// CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x i16> [[TMP2]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE8]], ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8475]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr [[__REINT_84714]], align 8 +// CHECK-NEXT: [[VGET_LANE18:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE18]], ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_84715]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x i16>, ptr [[__REINT_84724]], align 8 +// CHECK-NEXT: [[VGET_LANE28:%.*]] = extractelement <4 x i16> [[TMP6]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE28]], ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_84725]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x i16>, ptr [[__REINT_84734]], align 8 +// CHECK-NEXT: [[VGET_LANE38:%.*]] = extractelement <4 x i16> [[TMP8]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE38]], ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_84735]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x i16>, ptr [[__REINT_84744]], align 8 +// CHECK-NEXT: [[VGET_LANE48:%.*]] = extractelement <4 x i16> [[TMP10]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE48]], ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_84745]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load <4 x i16>, ptr [[__REINT_84754]], align 8 +// CHECK-NEXT: [[VGET_LANE58:%.*]] = extractelement <4 x i16> [[TMP12]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE58]], ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_84755]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <4 x half> [[C]], ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = load <4 x i16>, ptr [[__REINT_84764]], align 8 +// CHECK-NEXT: [[VGET_LANE68:%.*]] = extractelement <4 x i16> [[TMP14]], i32 3 +// CHECK-NEXT: store i16 [[VGET_LANE68]], ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_84765]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLSL_HIGH3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLSL_HIGH3_I]] // @@ -830,41 +830,41 @@ float32x4_t test_vfmlslq_lane_high_f16(float32x4_t a, float16x8_t b, float16x4_t // CHECK-LABEL: @test_vfmlsl_laneq_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 4 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 4 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLSL_LOW3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLSL_LOW3_I]] // @@ -874,41 +874,41 @@ float32x2_t test_vfmlsl_laneq_low_f16(float32x2_t a, float16x4_t b, float16x8_t // CHECK-LABEL: @test_vfmlsl_laneq_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 5 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: [[TMP16:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP17:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP18:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 5 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: [[TMP8:%.*]] = bitcast <2 x float> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP9:%.*]] = bitcast <4 x half> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP10:%.*]] = bitcast <4 x half> [[VECINIT31]] to <8 x i8> // CHECK-NEXT: [[VFMLSL_HIGH3_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> [[A]], <4 x half> [[B]], <4 x half> [[VECINIT31]]) // CHECK-NEXT: ret <2 x float> [[VFMLSL_HIGH3_I]] // @@ -918,73 +918,73 @@ float32x2_t test_vfmlsl_laneq_high_f16(float32x2_t a, float16x4_t b, float16x8_t // CHECK-LABEL: @test_vfmlslq_laneq_low_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85434:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85435:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85444:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85445:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85454:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85455:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85464:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85465:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[TMP17:%.*]] = load <8 x i16>, ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP17]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[TMP21:%.*]] = load <8 x i16>, ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP21]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[TMP25:%.*]] = load <8 x i16>, ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP25]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[TMP29:%.*]] = load <8 x i16>, ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP29]], i32 6 -// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85034:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85035:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85044:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85045:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85054:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85055:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85064:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85065:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[TMP8:%.*]] = load <8 x i16>, ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP8]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[TMP10:%.*]] = load <8 x i16>, ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP10]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[TMP12:%.*]] = load <8 x i16>, ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP12]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[TMP14:%.*]] = load <8 x i16>, ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP14]], i32 6 +// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLSL_LOW3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLSL_LOW3_I]] // @@ -994,73 +994,73 @@ float32x4_t test_vfmlslq_laneq_low_f16(float32x4_t a, float16x8_t b, float16x8_t // CHECK-LABEL: @test_vfmlslq_laneq_high_f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_854:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_854:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_8544:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_8545:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85414:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85415:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85424:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85425:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85434:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85435:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85444:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85445:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85454:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85455:%.*]] = alloca i16, align 2 -// CHECK-NEXT: [[__REINT_85464:%.*]] = alloca <8 x half>, align 16 -// CHECK-NEXT: [[__REINT1_85465:%.*]] = alloca i16, align 2 -// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr [[__REINT_854]], align 16 -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP1]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_854]], align 2 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP3]], i32 0 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x i16>, ptr [[__REINT_8544]], align 16 -// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP5]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_8545]], align 2 -// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP7]], i32 1 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[TMP9:%.*]] = load <8 x i16>, ptr [[__REINT_85414]], align 16 -// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP9]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85415]], align 2 -// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP11]], i32 2 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[TMP13:%.*]] = load <8 x i16>, ptr [[__REINT_85424]], align 16 -// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP13]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85425]], align 2 -// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP15]], i32 3 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[TMP17:%.*]] = load <8 x i16>, ptr [[__REINT_85434]], align 16 -// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP17]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[TMP19:%.*]] = load half, ptr [[__REINT1_85435]], align 2 -// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP19]], i32 4 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[TMP21:%.*]] = load <8 x i16>, ptr [[__REINT_85444]], align 16 -// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP21]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[TMP23:%.*]] = load half, ptr [[__REINT1_85445]], align 2 -// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP23]], i32 5 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[TMP25:%.*]] = load <8 x i16>, ptr [[__REINT_85454]], align 16 -// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP25]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[TMP27:%.*]] = load half, ptr [[__REINT1_85455]], align 2 -// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP27]], i32 6 -// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[TMP29:%.*]] = load <8 x i16>, ptr [[__REINT_85464]], align 16 -// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP29]], i32 7 -// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[TMP31:%.*]] = load half, ptr [[__REINT1_85465]], align 2 -// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP31]], i32 7 -// CHECK-NEXT: [[TMP32:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP33:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> +// CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_8504:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_8505:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85014:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85015:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85024:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85025:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85034:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85035:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85044:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85045:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85054:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85055:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[__REINT_85064:%.*]] = alloca <8 x half>, align 16 +// CHECK-NEXT: [[__REINT1_85065:%.*]] = alloca i16, align 2 +// CHECK-NEXT: store <8 x half> [[C:%.*]], ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, ptr [[__REINT_850]], align 16 +// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x i16> [[TMP0]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE]], ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[__REINT1_850]], align 2 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP1]], i32 0 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr [[__REINT_8504]], align 16 +// CHECK-NEXT: [[VGETQ_LANE8:%.*]] = extractelement <8 x i16> [[TMP2]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE8]], ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[__REINT1_8505]], align 2 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP3]], i32 1 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <8 x i16>, ptr [[__REINT_85014]], align 16 +// CHECK-NEXT: [[VGETQ_LANE18:%.*]] = extractelement <8 x i16> [[TMP4]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE18]], ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[__REINT1_85015]], align 2 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <8 x half> [[VECINIT11]], half [[TMP5]], i32 2 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[TMP6:%.*]] = load <8 x i16>, ptr [[__REINT_85024]], align 16 +// CHECK-NEXT: [[VGETQ_LANE28:%.*]] = extractelement <8 x i16> [[TMP6]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE28]], ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[__REINT1_85025]], align 2 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <8 x half> [[VECINIT21]], half [[TMP7]], i32 3 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[TMP8:%.*]] = load <8 x i16>, ptr [[__REINT_85034]], align 16 +// CHECK-NEXT: [[VGETQ_LANE38:%.*]] = extractelement <8 x i16> [[TMP8]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE38]], ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[TMP9:%.*]] = load half, ptr [[__REINT1_85035]], align 2 +// CHECK-NEXT: [[VECINIT41:%.*]] = insertelement <8 x half> [[VECINIT31]], half [[TMP9]], i32 4 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[TMP10:%.*]] = load <8 x i16>, ptr [[__REINT_85044]], align 16 +// CHECK-NEXT: [[VGETQ_LANE48:%.*]] = extractelement <8 x i16> [[TMP10]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE48]], ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[TMP11:%.*]] = load half, ptr [[__REINT1_85045]], align 2 +// CHECK-NEXT: [[VECINIT51:%.*]] = insertelement <8 x half> [[VECINIT41]], half [[TMP11]], i32 5 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[TMP12:%.*]] = load <8 x i16>, ptr [[__REINT_85054]], align 16 +// CHECK-NEXT: [[VGETQ_LANE58:%.*]] = extractelement <8 x i16> [[TMP12]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE58]], ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[TMP13:%.*]] = load half, ptr [[__REINT1_85055]], align 2 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <8 x half> [[VECINIT51]], half [[TMP13]], i32 6 +// CHECK-NEXT: store <8 x half> [[C]], ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[TMP14:%.*]] = load <8 x i16>, ptr [[__REINT_85064]], align 16 +// CHECK-NEXT: [[VGETQ_LANE68:%.*]] = extractelement <8 x i16> [[TMP14]], i32 7 +// CHECK-NEXT: store i16 [[VGETQ_LANE68]], ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[TMP15:%.*]] = load half, ptr [[__REINT1_85065]], align 2 +// CHECK-NEXT: [[VECINIT71:%.*]] = insertelement <8 x half> [[VECINIT61]], half [[TMP15]], i32 7 +// CHECK-NEXT: [[TMP16:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x half> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x half> [[VECINIT71]] to <16 x i8> // CHECK-NEXT: [[VFMLSL_HIGH3_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> [[A]], <8 x half> [[B]], <8 x half> [[VECINIT71]]) // CHECK-NEXT: ret <4 x float> [[VFMLSL_HIGH3_I]] // diff --git a/clang/test/CodeGen/aarch64-neon-vcmla.c b/clang/test/CodeGen/aarch64-neon-vcmla.c index 9cd046d63d1b520bcd2b5a282a5a31d88834d74a..02171527cc6a3288bdd27970c1ddb6257b60c85b 100644 --- a/clang/test/CodeGen/aarch64-neon-vcmla.c +++ b/clang/test/CodeGen/aarch64-neon-vcmla.c @@ -158,7 +158,7 @@ float16x4_t test_vcmla_lane_f16(float16x4_t acc, float16x4_t lhs, float16x4_t rh // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <2 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <2 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <2 x i32> [[DUP]] to <4 x half> // CHECK: [[RES:%.*]] = tail call <4 x half> @llvm.aarch64.neon.vcmla.rot0.v4f16(<4 x half> %acc, <4 x half> %lhs, <4 x half> [[DUP_FLT]]) // CHECK: ret <4 x half> [[RES]] @@ -176,7 +176,7 @@ float16x8_t test_vcmlaq_lane_f16(float16x8_t acc, float16x8_t lhs, float16x4_t r // CHECK-LABEL: @test_vcmlaq_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <4 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <4 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <4 x i32> [[DUP]] to <8 x half> // CHECK: [[RES:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vcmla.rot0.v8f16(<8 x half> %acc, <8 x half> %lhs, <8 x half> [[DUP_FLT]]) // CHECK: ret <8 x half> [[RES]] @@ -194,7 +194,7 @@ float32x2_t test_vcmla_lane_f32(float32x2_t acc, float32x2_t lhs, float32x2_t rh // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_laneq_f32( // CHECK: [[CPLX:%.*]] = bitcast <4 x float> %rhs to <2 x i64> -// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> undef, <1 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> poison, <1 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <1 x i64> [[DUP]] to <2 x float> // CHECK: [[RES:%.*]] = tail call <2 x float> @llvm.aarch64.neon.vcmla.rot0.v2f32(<2 x float> %acc, <2 x float> %lhs, <2 x float> [[DUP_FLT]]) // CHECK: ret <2 x float> [[RES]] @@ -204,7 +204,7 @@ float32x2_t test_vcmla_laneq_f32(float32x2_t acc, float32x2_t lhs, float32x4_t r // CHECK-LABEL: @test_vcmlaq_lane_f32( // CHECK: [[CPLX:%.*]] = bitcast <2 x float> %rhs to i64 -// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> undef, i64 [[CPLX]], i64 0 +// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> poison, i64 [[CPLX]], i64 0 // CHECK: [[CPLX2:%.*]] = bitcast <2 x i64> [[CPLX_VEC]] to <4 x float> // CHECK: [[DUP:%.*]] = shufflevector <4 x float> [[CPLX2]], <4 x float> poison, <4 x i32> // CHECK: [[RES:%.*]] = tail call <4 x float> @llvm.aarch64.neon.vcmla.rot0.v4f32(<4 x float> %acc, <4 x float> %lhs, <4 x float> [[DUP]]) @@ -232,7 +232,7 @@ float16x4_t test_vcmla_rot90_lane_f16(float16x4_t acc, float16x4_t lhs, float16x // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_rot90_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <2 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <2 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <2 x i32> [[DUP]] to <4 x half> // CHECK: [[RES:%.*]] = tail call <4 x half> @llvm.aarch64.neon.vcmla.rot90.v4f16(<4 x half> %acc, <4 x half> %lhs, <4 x half> [[DUP_FLT]]) // CHECK: ret <4 x half> [[RES]] @@ -250,7 +250,7 @@ float16x8_t test_vcmlaq_rot90_lane_f16(float16x8_t acc, float16x8_t lhs, float16 // CHECK-LABEL: @test_vcmlaq_rot90_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <4 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <4 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <4 x i32> [[DUP]] to <8 x half> // CHECK: [[RES:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vcmla.rot90.v8f16(<8 x half> %acc, <8 x half> %lhs, <8 x half> [[DUP_FLT]]) // CHECK: ret <8 x half> [[RES]] @@ -268,7 +268,7 @@ float32x2_t test_vcmla_rot90_lane_f32(float32x2_t acc, float32x2_t lhs, float32x // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_rot90_laneq_f32( // CHECK: [[CPLX:%.*]] = bitcast <4 x float> %rhs to <2 x i64> -// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> undef, <1 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> poison, <1 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <1 x i64> [[DUP]] to <2 x float> // CHECK: [[RES:%.*]] = tail call <2 x float> @llvm.aarch64.neon.vcmla.rot90.v2f32(<2 x float> %acc, <2 x float> %lhs, <2 x float> [[DUP_FLT]]) // CHECK: ret <2 x float> [[RES]] @@ -278,7 +278,7 @@ float32x2_t test_vcmla_rot90_laneq_f32(float32x2_t acc, float32x2_t lhs, float32 // CHECK-LABEL: @test_vcmlaq_rot90_lane_f32( // CHECK: [[CPLX:%.*]] = bitcast <2 x float> %rhs to i64 -// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> undef, i64 [[CPLX]], i64 0 +// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> poison, i64 [[CPLX]], i64 0 // CHECK: [[CPLX2:%.*]] = bitcast <2 x i64> [[CPLX_VEC]] to <4 x float> // CHECK: [[DUP:%.*]] = shufflevector <4 x float> [[CPLX2]], <4 x float> poison, <4 x i32> // CHECK: [[RES:%.*]] = tail call <4 x float> @llvm.aarch64.neon.vcmla.rot90.v4f32(<4 x float> %acc, <4 x float> %lhs, <4 x float> [[DUP]]) @@ -306,7 +306,7 @@ float16x4_t test_vcmla_rot180_lane_f16(float16x4_t acc, float16x4_t lhs, float16 // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_rot180_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <2 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <2 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <2 x i32> [[DUP]] to <4 x half> // CHECK: [[RES:%.*]] = tail call <4 x half> @llvm.aarch64.neon.vcmla.rot180.v4f16(<4 x half> %acc, <4 x half> %lhs, <4 x half> [[DUP_FLT]]) // CHECK: ret <4 x half> [[RES]] @@ -324,7 +324,7 @@ float16x8_t test_vcmlaq_rot180_lane_f16(float16x8_t acc, float16x8_t lhs, float1 // CHECK-LABEL: @test_vcmlaq_rot180_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <4 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <4 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <4 x i32> [[DUP]] to <8 x half> // CHECK: [[RES:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vcmla.rot180.v8f16(<8 x half> %acc, <8 x half> %lhs, <8 x half> [[DUP_FLT]]) // CHECK: ret <8 x half> [[RES]] @@ -342,7 +342,7 @@ float32x2_t test_vcmla_rot180_lane_f32(float32x2_t acc, float32x2_t lhs, float32 // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_rot180_laneq_f32( // CHECK: [[CPLX:%.*]] = bitcast <4 x float> %rhs to <2 x i64> -// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> undef, <1 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> poison, <1 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <1 x i64> [[DUP]] to <2 x float> // CHECK: [[RES:%.*]] = tail call <2 x float> @llvm.aarch64.neon.vcmla.rot180.v2f32(<2 x float> %acc, <2 x float> %lhs, <2 x float> [[DUP_FLT]]) // CHECK: ret <2 x float> [[RES]] @@ -352,7 +352,7 @@ float32x2_t test_vcmla_rot180_laneq_f32(float32x2_t acc, float32x2_t lhs, float3 // CHECK-LABEL: @test_vcmlaq_rot180_lane_f32( // CHECK: [[CPLX:%.*]] = bitcast <2 x float> %rhs to i64 -// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> undef, i64 [[CPLX]], i64 0 +// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> poison, i64 [[CPLX]], i64 0 // CHECK: [[CPLX2:%.*]] = bitcast <2 x i64> [[CPLX_VEC]] to <4 x float> // CHECK: [[DUP:%.*]] = shufflevector <4 x float> [[CPLX2]], <4 x float> poison, <4 x i32> // CHECK: [[RES:%.*]] = tail call <4 x float> @llvm.aarch64.neon.vcmla.rot180.v4f32(<4 x float> %acc, <4 x float> %lhs, <4 x float> [[DUP]]) @@ -380,7 +380,7 @@ float16x4_t test_vcmla_rot270_lane_f16(float16x4_t acc, float16x4_t lhs, float16 // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_rot270_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <2 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <2 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <2 x i32> [[DUP]] to <4 x half> // CHECK: [[RES:%.*]] = tail call <4 x half> @llvm.aarch64.neon.vcmla.rot270.v4f16(<4 x half> %acc, <4 x half> %lhs, <4 x half> [[DUP_FLT]]) // CHECK: ret <4 x half> [[RES]] @@ -398,7 +398,7 @@ float16x8_t test_vcmlaq_rot270_lane_f16(float16x8_t acc, float16x8_t lhs, float1 // CHECK-LABEL: @test_vcmlaq_rot270_laneq_f16( // CHECK: [[CPLX:%.*]] = bitcast <8 x half> %rhs to <4 x i32> -// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> undef, <4 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <4 x i32> [[CPLX]], <4 x i32> poison, <4 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <4 x i32> [[DUP]] to <8 x half> // CHECK: [[RES:%.*]] = tail call <8 x half> @llvm.aarch64.neon.vcmla.rot270.v8f16(<8 x half> %acc, <8 x half> %lhs, <8 x half> [[DUP_FLT]]) // CHECK: ret <8 x half> [[RES]] @@ -416,7 +416,7 @@ float32x2_t test_vcmla_rot270_lane_f32(float32x2_t acc, float32x2_t lhs, float32 // ACLE says this exists, but it won't map to a single instruction if lane > 1. // CHECK-LABEL: @test_vcmla_rot270_laneq_f32( // CHECK: [[CPLX:%.*]] = bitcast <4 x float> %rhs to <2 x i64> -// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> undef, <1 x i32> +// CHECK: [[DUP:%.*]] = shufflevector <2 x i64> [[CPLX]], <2 x i64> poison, <1 x i32> // CHECK: [[DUP_FLT:%.*]] = bitcast <1 x i64> [[DUP]] to <2 x float> // CHECK: [[RES:%.*]] = tail call <2 x float> @llvm.aarch64.neon.vcmla.rot270.v2f32(<2 x float> %acc, <2 x float> %lhs, <2 x float> [[DUP_FLT]]) // CHECK: ret <2 x float> [[RES]] @@ -426,7 +426,7 @@ float32x2_t test_vcmla_rot270_laneq_f32(float32x2_t acc, float32x2_t lhs, float3 // CHECK-LABEL: @test_vcmlaq_rot270_lane_f32( // CHECK: [[CPLX:%.*]] = bitcast <2 x float> %rhs to i64 -// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> undef, i64 [[CPLX]], i64 0 +// CHECK: [[CPLX_VEC:%.*]] = insertelement <2 x i64> poison, i64 [[CPLX]], i64 0 // CHECK: [[CPLX2:%.*]] = bitcast <2 x i64> [[DUP]] to <4 x float> // CHECK: [[DUP:%.*]] = shufflevector <4 x float> [[CPLX2]], <4 x float> poison, <4 x i32> // CHECK: [[RES:%.*]] = tail call <4 x float> @llvm.aarch64.neon.vcmla.rot270.v4f32(<4 x float> %acc, <4 x float> %lhs, <4 x float> [[DUP]]) diff --git a/clang/test/CodeGen/aarch64-poly64.c b/clang/test/CodeGen/aarch64-poly64.c index 09d977c64cbca9589b23c44626352aa42813ada5..c404b7c020d1b933bc61e95a68cd6b506bb37f38 100644 --- a/clang/test/CodeGen/aarch64-poly64.c +++ b/clang/test/CodeGen/aarch64-poly64.c @@ -121,13 +121,13 @@ poly64x1_t test_vcreate_p64(uint64_t a) { } // CHECK-LABEL: define{{.*}} <1 x i64> @test_vdup_n_p64(i64 noundef %a) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> poison, i64 %a, i32 0 // CHECK: ret <1 x i64> [[VECINIT_I]] poly64x1_t test_vdup_n_p64(poly64_t a) { return vdup_n_p64(a); } // CHECK-LABEL: define{{.*}} <2 x i64> @test_vdupq_n_p64(i64 noundef %a) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1 // CHECK: ret <2 x i64> [[VECINIT1_I]] poly64x2_t test_vdupq_n_p64(poly64_t a) { @@ -135,14 +135,14 @@ poly64x2_t test_vdupq_n_p64(poly64_t a) { } // CHECK-LABEL: define{{.*}} <1 x i64> @test_vmov_n_p64(i64 noundef %a) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> poison, i64 %a, i32 0 // CHECK: ret <1 x i64> [[VECINIT_I]] poly64x1_t test_vmov_n_p64(poly64_t a) { return vmov_n_p64(a); } // CHECK-LABEL: define{{.*}} <2 x i64> @test_vmovq_n_p64(i64 noundef %a) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1 // CHECK: ret <2 x i64> [[VECINIT1_I]] poly64x2_t test_vmovq_n_p64(poly64_t a) { diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i32.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i32.c index e444321be41b2cbd0404fb8cfe209e8c0d8cec80..55d2e355897f7294dd5a06cac9030122f238ed50 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i32.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i32.c @@ -30,7 +30,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv4i32(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za32_u32(svbool_t pn, svbool_t pm, svuint32_t zn) { +void test_svaddha_za32_u32(svbool_t pn, svbool_t pm, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za32, _u32, _m)(0, pn, pm, zn); } @@ -50,7 +50,7 @@ void test_svaddha_za32_u32(svbool_t pn, svbool_t pm, svuint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv4i32(i32 3, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za32_u32_1(svbool_t pn, svbool_t pm, svuint32_t zn) { +void test_svaddha_za32_u32_1(svbool_t pn, svbool_t pm, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za32, _u32, _m)(3, pn, pm, zn); } @@ -70,7 +70,7 @@ void test_svaddha_za32_u32_1(svbool_t pn, svbool_t pm, svuint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv4i32(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za32_s32(svbool_t pn, svbool_t pm, svint32_t zn) { +void test_svaddha_za32_s32(svbool_t pn, svbool_t pm, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za32, _s32, _m)(0, pn, pm, zn); } @@ -90,7 +90,7 @@ void test_svaddha_za32_s32(svbool_t pn, svbool_t pm, svint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv4i32(i32 3, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za32_s32_1(svbool_t pn, svbool_t pm, svint32_t zn) { +void test_svaddha_za32_s32_1(svbool_t pn, svbool_t pm, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za32, _s32, _m)(3, pn, pm, zn); } @@ -110,7 +110,7 @@ void test_svaddha_za32_s32_1(svbool_t pn, svbool_t pm, svint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv4i32(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za32_u32(svbool_t pn, svbool_t pm, svuint32_t zn) { +void test_svaddva_za32_u32(svbool_t pn, svbool_t pm, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za32, _u32, _m)(0, pn, pm, zn); } @@ -130,7 +130,7 @@ void test_svaddva_za32_u32(svbool_t pn, svbool_t pm, svuint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv4i32(i32 3, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za32_u32_1(svbool_t pn, svbool_t pm, svuint32_t zn) { +void test_svaddva_za32_u32_1(svbool_t pn, svbool_t pm, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za32, _u32, _m)(3, pn, pm, zn); } @@ -150,7 +150,7 @@ void test_svaddva_za32_u32_1(svbool_t pn, svbool_t pm, svuint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv4i32(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za32_s32(svbool_t pn, svbool_t pm, svint32_t zn) { +void test_svaddva_za32_s32(svbool_t pn, svbool_t pm, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za32, _s32, _m)(0, pn, pm, zn); } @@ -170,7 +170,7 @@ void test_svaddva_za32_s32(svbool_t pn, svbool_t pm, svint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv4i32(i32 3, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za32_s32_1(svbool_t pn, svbool_t pm, svint32_t zn) { +void test_svaddva_za32_s32_1(svbool_t pn, svbool_t pm, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za32, _s32, _m)(3, pn, pm, zn); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i64.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i64.c index 4b2f71d607eb60ca5206376ec0e0984a90ecf22d..8e9c2e7da46a3aed8f9cdb76e350c680decf5f00 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i64.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_add-i64.c @@ -30,7 +30,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv2i64(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za64_u64(svbool_t pn, svbool_t pm, svuint64_t zn) { +void test_svaddha_za64_u64(svbool_t pn, svbool_t pm, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za64, _u64, _m)(0, pn, pm, zn); } @@ -50,7 +50,7 @@ void test_svaddha_za64_u64(svbool_t pn, svbool_t pm, svuint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv2i64(i32 7, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za64_u64_1(svbool_t pn, svbool_t pm, svuint64_t zn) { +void test_svaddha_za64_u64_1(svbool_t pn, svbool_t pm, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za64, _u64, _m)(7, pn, pm, zn); } @@ -70,7 +70,7 @@ void test_svaddha_za64_u64_1(svbool_t pn, svbool_t pm, svuint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv2i64(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za64_s64(svbool_t pn, svbool_t pm, svint64_t zn) { +void test_svaddha_za64_s64(svbool_t pn, svbool_t pm, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za64, _s64, _m)(0, pn, pm, zn); } @@ -90,7 +90,7 @@ void test_svaddha_za64_s64(svbool_t pn, svbool_t pm, svint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addha.nxv2i64(i32 7, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddha_za64_s64_1(svbool_t pn, svbool_t pm, svint64_t zn) { +void test_svaddha_za64_s64_1(svbool_t pn, svbool_t pm, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddha_za64, _s64, _m)(7, pn, pm, zn); } @@ -110,7 +110,7 @@ void test_svaddha_za64_s64_1(svbool_t pn, svbool_t pm, svint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv2i64(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za64_u64(svbool_t pn, svbool_t pm, svuint64_t zn) { +void test_svaddva_za64_u64(svbool_t pn, svbool_t pm, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za64, _u64, _m)(0, pn, pm, zn); } @@ -130,7 +130,7 @@ void test_svaddva_za64_u64(svbool_t pn, svbool_t pm, svuint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv2i64(i32 7, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za64_u64_1(svbool_t pn, svbool_t pm, svuint64_t zn) { +void test_svaddva_za64_u64_1(svbool_t pn, svbool_t pm, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za64, _u64, _m)(7, pn, pm, zn); } @@ -150,7 +150,7 @@ void test_svaddva_za64_u64_1(svbool_t pn, svbool_t pm, svuint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv2i64(i32 0, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za64_s64(svbool_t pn, svbool_t pm, svint64_t zn) { +void test_svaddva_za64_s64(svbool_t pn, svbool_t pm, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za64, _s64, _m)(0, pn, pm, zn); } @@ -170,7 +170,7 @@ void test_svaddva_za64_s64(svbool_t pn, svbool_t pm, svint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.addva.nxv2i64(i32 7, [[TMP0]], [[TMP1]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svaddva_za64_s64_1(svbool_t pn, svbool_t pm, svint64_t zn) { +void test_svaddva_za64_s64_1(svbool_t pn, svbool_t pm, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svaddva_za64, _s64, _m)(7, pn, pm, zn); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1.c index 5622568c4cd76b6e876079dd0d69ca696df3a66f..e17782db222b60bb776f846c5a4fafccd440d75a 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1.c @@ -22,7 +22,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[PTR]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_hor_za8(0, slice_base, pg, ptr); svld1_hor_za8(0, slice_base + 15, pg, ptr); } @@ -45,7 +45,7 @@ void test_svld1_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr) __arm // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[PTR]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_za16(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_hor_za16(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_hor_za16(0, slice_base, pg, ptr); svld1_hor_za16(1, slice_base + 7, pg, ptr); } @@ -68,7 +68,7 @@ void test_svld1_hor_za16(uint32_t slice_base, svbool_t pg, const void *ptr) __ar // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[PTR]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_za32(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_hor_za32(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_hor_za32(0, slice_base, pg, ptr); svld1_hor_za32(3, slice_base + 3, pg, ptr); } @@ -91,7 +91,7 @@ void test_svld1_hor_za32(uint32_t slice_base, svbool_t pg, const void *ptr) __ar // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[PTR]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_za64(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_hor_za64(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_hor_za64(0, slice_base, pg, ptr); svld1_hor_za64(7, slice_base + 1, pg, ptr); } @@ -112,7 +112,7 @@ void test_svld1_hor_za64(uint32_t slice_base, svbool_t pg, const void *ptr) __ar // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[PTR]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_za128(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_hor_za128(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_hor_za128(0, slice_base, pg, ptr); svld1_hor_za128(15, slice_base, pg, ptr); } @@ -133,7 +133,7 @@ void test_svld1_hor_za128(uint32_t slice_base, svbool_t pg, const void *ptr) __a // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[PTR]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_za8(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_ver_za8(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_ver_za8(0, slice_base, pg, ptr); svld1_ver_za8(0, slice_base + 15, pg, ptr); } @@ -156,7 +156,7 @@ void test_svld1_ver_za8(uint32_t slice_base, svbool_t pg, const void *ptr) __arm // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[PTR]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_za16(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_ver_za16(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_ver_za16(0, slice_base, pg, ptr); svld1_ver_za16(1, slice_base + 7, pg, ptr); } @@ -179,7 +179,7 @@ void test_svld1_ver_za16(uint32_t slice_base, svbool_t pg, const void *ptr) __ar // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[PTR]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_za32(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_ver_za32(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_ver_za32(0, slice_base, pg, ptr); svld1_ver_za32(3, slice_base + 3, pg, ptr); } @@ -202,7 +202,7 @@ void test_svld1_ver_za32(uint32_t slice_base, svbool_t pg, const void *ptr) __ar // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[PTR]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_za64(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_ver_za64(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_ver_za64(0, slice_base, pg, ptr); svld1_ver_za64(7, slice_base + 1, pg, ptr); } @@ -223,7 +223,7 @@ void test_svld1_ver_za64(uint32_t slice_base, svbool_t pg, const void *ptr) __ar // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[PTR]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_za128(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming { +void test_svld1_ver_za128(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_shared_za { svld1_ver_za128(0, slice_base, pg, ptr); svld1_ver_za128(15, slice_base, pg, ptr); } diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1_vnum.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1_vnum.c index 0fe7dcfc0a79946ee8d675b6c44f57c114c5e4da..0fa77e1144a7d95f4ed11ffa4915c8dccdcbfadf 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1_vnum.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ld1_vnum.c @@ -28,7 +28,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_hor_vnum_za8(0, slice_base, pg, ptr, vnum); svld1_hor_vnum_za8(0, slice_base + 15, pg, ptr, vnum); } @@ -57,7 +57,7 @@ void test_svld1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_hor_vnum_za16(0, slice_base, pg, ptr, vnum); svld1_hor_vnum_za16(1, slice_base + 7, pg, ptr, vnum); } @@ -86,7 +86,7 @@ void test_svld1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_hor_vnum_za32(0, slice_base, pg, ptr, vnum); svld1_hor_vnum_za32(3, slice_base + 3, pg, ptr, vnum); } @@ -115,7 +115,7 @@ void test_svld1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_hor_vnum_za64(0, slice_base, pg, ptr, vnum); svld1_hor_vnum_za64(7, slice_base + 1, pg, ptr, vnum); } @@ -142,7 +142,7 @@ void test_svld1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_hor_vnum_za128(0, slice_base, pg, ptr, vnum); svld1_hor_vnum_za128(15, slice_base, pg, ptr, vnum); } @@ -169,7 +169,7 @@ void test_svld1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_ver_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_ver_vnum_za8(0, slice_base, pg, ptr, vnum); svld1_ver_vnum_za8(0, slice_base + 15, pg, ptr, vnum); } @@ -198,7 +198,7 @@ void test_svld1_ver_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr, i // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_ver_vnum_za16(0, slice_base, pg, ptr, vnum); svld1_ver_vnum_za16(1, slice_base + 7, pg, ptr, vnum); } @@ -227,7 +227,7 @@ void test_svld1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_ver_vnum_za32(0, slice_base, pg, ptr, vnum); svld1_ver_vnum_za32(3, slice_base + 3, pg, ptr, vnum); } @@ -256,7 +256,7 @@ void test_svld1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_ver_vnum_za64(0, slice_base, pg, ptr, vnum); svld1_ver_vnum_za64(7, slice_base + 1, pg, ptr, vnum); } @@ -283,7 +283,7 @@ void test_svld1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svld1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming { +void test_svld1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svld1_ver_vnum_za128(0, slice_base, pg, ptr, vnum); svld1_ver_vnum_za128(15, slice_base, pg, ptr, vnum); } diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ldr.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ldr.c index 9af0778e89c5ec0f5f65545569fa945992c59039..314c9645dd4f7d3666df02acd106901730a3ee24 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ldr.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_ldr.c @@ -12,7 +12,7 @@ // CHECK-NEXT: tail call void @llvm.aarch64.sme.ldr(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_svldr_vnum_za(uint32_t slice_base, const void *ptr) { +void test_svldr_vnum_za(uint32_t slice_base, const void *ptr) __arm_shared_za { svldr_vnum_za(slice_base, ptr, 0); } @@ -22,7 +22,7 @@ void test_svldr_vnum_za(uint32_t slice_base, const void *ptr) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.ldr(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 15) // CHECK-NEXT: ret void // -void test_svldr_vnum_za_1(uint32_t slice_base, const void *ptr) { +void test_svldr_vnum_za_1(uint32_t slice_base, const void *ptr) __arm_shared_za { svldr_vnum_za(slice_base, ptr, 15); } @@ -32,7 +32,7 @@ void test_svldr_vnum_za_1(uint32_t slice_base, const void *ptr) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.ldr(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_svldr_za(uint32_t slice_base, const void *ptr) { +void test_svldr_za(uint32_t slice_base, const void *ptr) __arm_shared_za { svldr_za(slice_base, ptr); } @@ -43,7 +43,7 @@ void test_svldr_za(uint32_t slice_base, const void *ptr) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.ldr(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 [[TMP0:%.*]]) // CHECK-NEXT: ret void // -void test_svldr_vnum_za_var(uint32_t slice_base, const void *ptr, int64_t vnum) { +void test_svldr_vnum_za_var(uint32_t slice_base, const void *ptr, int64_t vnum) __arm_shared_za { svldr_vnum_za(slice_base, ptr, vnum); } @@ -53,6 +53,6 @@ void test_svldr_vnum_za_var(uint32_t slice_base, const void *ptr, int64_t vnum) // CHECK-NEXT: tail call void @llvm.aarch64.sme.ldr(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 16) // CHECK-NEXT: ret void // -void test_svldr_vnum_za_2(uint32_t slice_base, const void *ptr) { +void test_svldr_vnum_za_2(uint32_t slice_base, const void *ptr) __arm_shared_za { svldr_vnum_za(slice_base, ptr, 16); } diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za32.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za32.c index 88206eec76b97e6331ba65f725a671e4e37b91e1..e84f31c2dfa92a8e8788ff3c534f9c945a5ec02d 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za32.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za32.c @@ -26,7 +26,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.smopa.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svint8_t zm) { +void test_svmopa_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za32, _s8, _m)(0, pn, pm, zn, zm); } @@ -42,7 +42,7 @@ void test_svmopa_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svint8_t zm) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.umopa.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svuint8_t zm) { +void test_svmopa_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za32, _u8, _m)(0, pn, pm, zn, zm); } @@ -62,7 +62,7 @@ void test_svmopa_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svuint8_t zm) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mopa.wide.nxv8bf16(i32 0, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za32_bf16(svbool_t pn, svbool_t pm, svbfloat16_t zn, svbfloat16_t zm) { +void test_svmopa_za32_bf16(svbool_t pn, svbool_t pm, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za32, _bf16, _m)(0, pn, pm, zn, zm); } @@ -82,7 +82,7 @@ void test_svmopa_za32_bf16(svbool_t pn, svbool_t pm, svbfloat16_t zn, svbfloat16 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mopa.wide.nxv8f16(i32 1, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za32_f16(svbool_t pn, svbool_t pm, svfloat16_t zn, svfloat16_t zm) { +void test_svmopa_za32_f16(svbool_t pn, svbool_t pm, svfloat16_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za32, _f16, _m)(1, pn, pm, zn, zm); } @@ -102,7 +102,7 @@ void test_svmopa_za32_f16(svbool_t pn, svbool_t pm, svfloat16_t zn, svfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mopa.nxv4f32(i32 1, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za32_f32(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) { +void test_svmopa_za32_f32(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za32, _f32, _m)(1, pn, pm, zn, zm); } @@ -118,7 +118,7 @@ void test_svmopa_za32_f32(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.sumopa.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svsumopa_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svuint8_t zm) { +void test_svsumopa_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svsumopa_za32, _s8, _m)(0, pn, pm, zn, zm); } @@ -134,7 +134,7 @@ void test_svsumopa_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svuint8_t zm) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.usmopa.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svusmopa_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svint8_t zm) { +void test_svusmopa_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svusmopa_za32, _u8, _m)(0, pn, pm, zn, zm); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za64.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za64.c index 1a1ab1e00d0ec620292f19a14edb1263f49e758c..1b22eb64e9e36aef4a1abe4597282f6cf7eddc6b 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za64.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mopa-za64.c @@ -30,7 +30,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.smopa.wide.nxv8i16(i32 7, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) { +void test_svmopa_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za64, _s16, _m)(7, pn, pm, zn, zm); } @@ -50,7 +50,7 @@ void test_svmopa_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.umopa.wide.nxv8i16(i32 0, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm) { +void test_svmopa_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za64, _u16, _m)(0, pn, pm, zn, zm); } @@ -70,7 +70,7 @@ void test_svmopa_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mopa.nxv2f64(i32 7, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmopa_za64_f64(svbool_t pn, svbool_t pm, svfloat64_t zn, svfloat64_t zm) { +void test_svmopa_za64_f64(svbool_t pn, svbool_t pm, svfloat64_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmopa_za64, _f64, _m)(7, pn, pm, zn, zm); } @@ -90,7 +90,7 @@ void test_svmopa_za64_f64(svbool_t pn, svbool_t pm, svfloat64_t zn, svfloat64_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.sumopa.wide.nxv8i16(i32 0, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svsumopa_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svuint16_t zm) { +void test_svsumopa_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svsumopa_za64, _s16, _m)(0, pn, pm, zn, zm); } @@ -110,7 +110,7 @@ void test_svsumopa_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svuint16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.usmopa.wide.nxv8i16(i32 7, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svusmopa_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svint16_t zm) { +void test_svusmopa_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svusmopa_za64, _u16, _m)(7, pn, pm, zn, zm); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za32.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za32.c index 1633cc6ed32e059fdaffe907e7fa5fbd425fe563..0ff97ff92f7147ee381a1ee03478716d196deeac 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za32.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za32.c @@ -26,7 +26,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.smops.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svint8_t zm) { +void test_svmops_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za32, _s8, _m)(0, pn, pm, zn, zm); } @@ -42,7 +42,7 @@ void test_svmops_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svint8_t zm) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.umops.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svuint8_t zm) { +void test_svmops_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za32, _u8, _m)(0, pn, pm, zn, zm); } @@ -62,7 +62,7 @@ void test_svmops_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svuint8_t zm) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mops.wide.nxv8bf16(i32 0, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za32_bf16(svbool_t pn, svbool_t pm, svbfloat16_t zn, svbfloat16_t zm) { +void test_svmops_za32_bf16(svbool_t pn, svbool_t pm, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za32, _bf16, _m)(0, pn, pm, zn, zm); } @@ -82,7 +82,7 @@ void test_svmops_za32_bf16(svbool_t pn, svbool_t pm, svbfloat16_t zn, svbfloat16 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mops.wide.nxv8f16(i32 1, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za32_f16(svbool_t pn, svbool_t pm, svfloat16_t zn, svfloat16_t zm) { +void test_svmops_za32_f16(svbool_t pn, svbool_t pm, svfloat16_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za32, _f16, _m)(1, pn, pm, zn, zm); } @@ -102,7 +102,7 @@ void test_svmops_za32_f16(svbool_t pn, svbool_t pm, svfloat16_t zn, svfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mops.nxv4f32(i32 1, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za32_f32(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) { +void test_svmops_za32_f32(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za32, _f32, _m)(1, pn, pm, zn, zm); } @@ -118,7 +118,7 @@ void test_svmops_za32_f32(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.sumops.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svsumops_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svuint8_t zm) { +void test_svsumops_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svsumops_za32, _s8, _m)(0, pn, pm, zn, zm); } @@ -134,7 +134,7 @@ void test_svsumops_za32_s8(svbool_t pn, svbool_t pm, svint8_t zn, svuint8_t zm) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.usmops.wide.nxv16i8(i32 0, [[PN]], [[PM]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svusmops_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svint8_t zm) { +void test_svusmops_za32_u8(svbool_t pn, svbool_t pm, svuint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svusmops_za32, _u8, _m)(0, pn, pm, zn, zm); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za64.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za64.c index b17df30c0f8513b6426ec89c56aafb7977b1cd02..5b190a7f9b748e0f548defb6766e0a904adfec0c 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za64.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_mops-za64.c @@ -30,7 +30,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.smops.wide.nxv8i16(i32 7, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) { +void test_svmops_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za64, _s16, _m)(7, pn, pm, zn, zm); } @@ -50,7 +50,7 @@ void test_svmops_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.umops.wide.nxv8i16(i32 0, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm) { +void test_svmops_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za64, _u16, _m)(0, pn, pm, zn, zm); } @@ -70,7 +70,7 @@ void test_svmops_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.mops.nxv2f64(i32 7, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svmops_za64_f64(svbool_t pn, svbool_t pm, svfloat64_t zn, svfloat64_t zm) { +void test_svmops_za64_f64(svbool_t pn, svbool_t pm, svfloat64_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svmops_za64, _f64, _m)(7, pn, pm, zn, zm); } @@ -90,7 +90,7 @@ void test_svmops_za64_f64(svbool_t pn, svbool_t pm, svfloat64_t zn, svfloat64_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.sumops.wide.nxv8i16(i32 0, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svsumops_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svuint16_t zm) { +void test_svsumops_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svsumops_za64, _s16, _m)(0, pn, pm, zn, zm); } @@ -110,7 +110,7 @@ void test_svsumops_za64_s16(svbool_t pn, svbool_t pm, svint16_t zn, svuint16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.usmops.wide.nxv8i16(i32 7, [[TMP0]], [[TMP1]], [[ZN]], [[ZM]]) // CHECK-CXX-NEXT: ret void // -void test_svusmops_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svint16_t zm) { +void test_svusmops_za64_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svusmops_za64, _u16, _m)(7, pn, pm, zn, zm); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_read.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_read.c index d63900129f9946e484d56d2721fc9bc0a4859523..843a96da9027808b738078a9a6fd0868ba8a24e6 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_read.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_read.c @@ -26,7 +26,7 @@ // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_hor_za8_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_hor_za8_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za8, _s8, _m)(zd, pg, 0, slice_base); } @@ -44,7 +44,7 @@ svint8_t test_svread_hor_za8_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) { // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_hor_za8_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_hor_za8_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; return SME_ACLE_FUNC(svread_hor_za8, _s8, _m)(zd, pg, 0, slice); } @@ -63,7 +63,7 @@ svint8_t test_svread_hor_za8_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_hor_za16_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_hor_za16_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za16, _s16, _m)(zd, pg, 0, slice_base); } @@ -83,7 +83,7 @@ svint16_t test_svread_hor_za16_s16(svint16_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_hor_za16_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_hor_za16_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_hor_za16, _s16, _m)(zd, pg, 1, slice); } @@ -102,7 +102,7 @@ svint16_t test_svread_hor_za16_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_hor_za32_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_hor_za32_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za32, _s32, _m)(zd, pg, 0, slice_base); } @@ -122,7 +122,7 @@ svint32_t test_svread_hor_za32_s32(svint32_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_hor_za32_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_hor_za32_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; return SME_ACLE_FUNC(svread_hor_za32, _s32, _m)(zd, pg, 3, slice); } @@ -141,7 +141,7 @@ svint32_t test_svread_hor_za32_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_hor_za64_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_hor_za64_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za64, _s64, _m)(zd, pg, 0, slice_base); } @@ -161,7 +161,7 @@ svint64_t test_svread_hor_za64_s64(svint64_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_hor_za64_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_hor_za64_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; return SME_ACLE_FUNC(svread_hor_za64, _s64, _m)(zd, pg, 7, slice); } @@ -178,7 +178,7 @@ svint64_t test_svread_hor_za64_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_hor_za8_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_hor_za8_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za8, _u8, _m)(zd, pg, 0, slice_base); } @@ -196,7 +196,7 @@ svuint8_t test_svread_hor_za8_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_hor_za8_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_hor_za8_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; return SME_ACLE_FUNC(svread_hor_za8, _u8, _m)(zd, pg, 0, slice); } @@ -215,7 +215,7 @@ svuint8_t test_svread_hor_za8_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_hor_za16_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_hor_za16_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za16, _u16, _m)(zd, pg, 0, slice_base); } @@ -235,7 +235,7 @@ svuint16_t test_svread_hor_za16_u16(svuint16_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_hor_za16_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_hor_za16_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_hor_za16, _u16, _m)(zd, pg, 1, slice); } @@ -254,7 +254,7 @@ svuint16_t test_svread_hor_za16_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_hor_za32_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_hor_za32_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za32, _u32, _m)(zd, pg, 0, slice_base); } @@ -274,7 +274,7 @@ svuint32_t test_svread_hor_za32_u32(svuint32_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_hor_za32_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_hor_za32_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; return SME_ACLE_FUNC(svread_hor_za32, _u32, _m)(zd, pg, 3, slice); } @@ -293,7 +293,7 @@ svuint32_t test_svread_hor_za32_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_hor_za64_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_hor_za64_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za64, _u64, _m)(zd, pg, 0, slice_base); } @@ -313,7 +313,7 @@ svuint64_t test_svread_hor_za64_u64(svuint64_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_hor_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_hor_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; return SME_ACLE_FUNC(svread_hor_za64, _u64, _m)(zd, pg, 7, slice); } @@ -332,7 +332,7 @@ svuint64_t test_svread_hor_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8f16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_hor_za16_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_hor_za16_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za16, _f16, _m)(zd, pg, 0, slice_base); } @@ -352,7 +352,7 @@ svfloat16_t test_svread_hor_za16_f16(svfloat16_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8f16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_hor_za16_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_hor_za16_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_hor_za16, _f16, _m)(zd, pg, 1, slice); } @@ -371,7 +371,7 @@ svfloat16_t test_svread_hor_za16_f16_1(svfloat16_t zd, svbool_t pg, uint32_t sli // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8bf16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_hor_za16_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_hor_za16_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za16, _bf16, _m)(zd, pg, 0, slice_base); } @@ -391,7 +391,7 @@ svbfloat16_t test_svread_hor_za16_bf16(svbfloat16_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv8bf16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_hor_za16_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_hor_za16_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_hor_za16, _bf16, _m)(zd, pg, 1, slice); } @@ -410,7 +410,7 @@ svbfloat16_t test_svread_hor_za16_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv4f32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_hor_za32_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_hor_za32_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za32, _f32, _m)(zd, pg, 0, slice_base); } @@ -430,7 +430,7 @@ svfloat32_t test_svread_hor_za32_f32(svfloat32_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv4f32( [[ZD]], [[TMP0]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_hor_za32_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_hor_za32_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; return SME_ACLE_FUNC(svread_hor_za32, _f32, _m)(zd, pg, 3, slice); } @@ -449,7 +449,7 @@ svfloat32_t test_svread_hor_za32_f32_1(svfloat32_t zd, svbool_t pg, uint32_t sli // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv2f64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_hor_za64_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_hor_za64_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za64, _f64, _m)(zd, pg, 0, slice_base); } @@ -469,7 +469,7 @@ svfloat64_t test_svread_hor_za64_f64(svfloat64_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv2f64( [[ZD]], [[TMP0]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_hor_za64_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_hor_za64_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; return SME_ACLE_FUNC(svread_hor_za64, _f64, _m)(zd, pg, 7, slice); } @@ -486,7 +486,7 @@ svfloat64_t test_svread_hor_za64_f64_1(svfloat64_t zd, svbool_t pg, uint32_t sli // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_hor_za128_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_hor_za128_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s8, _m)(zd, pg, 0, slice_base); } @@ -502,7 +502,7 @@ svint8_t test_svread_hor_za128_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_hor_za128_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_hor_za128_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s8, _m)(zd, pg, 15, slice_base); } @@ -520,7 +520,7 @@ svint8_t test_svread_hor_za128_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_hor_za128_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_hor_za128_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s16, _m)(zd, pg, 0, slice_base); } @@ -538,7 +538,7 @@ svint16_t test_svread_hor_za128_s16(svint16_t zd, svbool_t pg, uint32_t slice_ba // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_hor_za128_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_hor_za128_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s16, _m)(zd, pg, 15, slice_base); } @@ -556,7 +556,7 @@ svint16_t test_svread_hor_za128_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_hor_za128_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_hor_za128_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s32, _m)(zd, pg, 0, slice_base); } @@ -574,7 +574,7 @@ svint32_t test_svread_hor_za128_s32(svint32_t zd, svbool_t pg, uint32_t slice_ba // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_hor_za128_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_hor_za128_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s32, _m)(zd, pg, 15, slice_base); } @@ -592,7 +592,7 @@ svint32_t test_svread_hor_za128_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_hor_za128_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_hor_za128_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s64, _m)(zd, pg, 0, slice_base); } @@ -610,7 +610,7 @@ svint64_t test_svread_hor_za128_s64(svint64_t zd, svbool_t pg, uint32_t slice_ba // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_hor_za128_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_hor_za128_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _s64, _m)(zd, pg, 15, slice_base); } @@ -626,7 +626,7 @@ svint64_t test_svread_hor_za128_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_hor_za128_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_hor_za128_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u8, _m)(zd, pg, 0, slice_base); } @@ -642,7 +642,7 @@ svuint8_t test_svread_hor_za128_u8(svuint8_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_hor_za128_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_hor_za128_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u8, _m)(zd, pg, 15, slice_base); } @@ -660,7 +660,7 @@ svuint8_t test_svread_hor_za128_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_hor_za128_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_hor_za128_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u16, _m)(zd, pg, 0, slice_base); } @@ -678,7 +678,7 @@ svuint16_t test_svread_hor_za128_u16(svuint16_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8i16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_hor_za128_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_hor_za128_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u16, _m)(zd, pg, 15, slice_base); } @@ -696,7 +696,7 @@ svuint16_t test_svread_hor_za128_u16_1(svuint16_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_hor_za128_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_hor_za128_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u32, _m)(zd, pg, 0, slice_base); } @@ -714,7 +714,7 @@ svuint32_t test_svread_hor_za128_u32(svuint32_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv4i32( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_hor_za128_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_hor_za128_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u32, _m)(zd, pg, 15, slice_base); } @@ -732,7 +732,7 @@ svuint32_t test_svread_hor_za128_u32_1(svuint32_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_hor_za128_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_hor_za128_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u64, _m)(zd, pg, 0, slice_base); } @@ -750,7 +750,7 @@ svuint64_t test_svread_hor_za128_u64(svuint64_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv2i64( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_hor_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_hor_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _u64, _m)(zd, pg, 15, slice_base); } @@ -768,7 +768,7 @@ svuint64_t test_svread_hor_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8f16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_hor_za128_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_hor_za128_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _f16, _m)(zd, pg, 0, slice_base); } @@ -786,7 +786,7 @@ svfloat16_t test_svread_hor_za128_f16(svfloat16_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8f16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_hor_za128_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_hor_za128_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _f16, _m)(zd, pg, 15, slice_base); } @@ -804,7 +804,7 @@ svfloat16_t test_svread_hor_za128_f16_1(svfloat16_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8bf16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_hor_za128_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_hor_za128_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _bf16, _m)(zd, pg, 0, slice_base); } @@ -822,7 +822,7 @@ svbfloat16_t test_svread_hor_za128_bf16(svbfloat16_t zd, svbool_t pg, uint32_t s // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv8bf16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_hor_za128_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_hor_za128_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _bf16, _m)(zd, pg, 15, slice_base); } @@ -840,7 +840,7 @@ svbfloat16_t test_svread_hor_za128_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv4f32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_hor_za128_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_hor_za128_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _f32, _m)(zd, pg, 0, slice_base); } @@ -858,7 +858,7 @@ svfloat32_t test_svread_hor_za128_f32(svfloat32_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv4f32( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_hor_za128_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_hor_za128_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _f32, _m)(zd, pg, 15, slice_base); } @@ -876,7 +876,7 @@ svfloat32_t test_svread_hor_za128_f32_1(svfloat32_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv2f64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_hor_za128_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_hor_za128_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _f64, _m)(zd, pg, 0, slice_base); } @@ -894,7 +894,7 @@ svfloat64_t test_svread_hor_za128_f64(svfloat64_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv2f64( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_hor_za128_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_hor_za128_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_hor_za128, _f64, _m)(zd, pg, 15, slice_base); } @@ -910,7 +910,7 @@ svfloat64_t test_svread_hor_za128_f64_1(svfloat64_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_ver_za8_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_ver_za8_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za8, _s8, _m)(zd, pg, 0, slice_base); } @@ -928,7 +928,7 @@ svint8_t test_svread_ver_za8_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_ver_za8_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_ver_za8_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; return SME_ACLE_FUNC(svread_ver_za8, _s8, _m)(zd, pg, 0, slice); } @@ -947,7 +947,7 @@ svint8_t test_svread_ver_za8_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_ver_za16_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_ver_za16_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za16, _s16, _m)(zd, pg, 0, slice_base); } @@ -967,7 +967,7 @@ svint16_t test_svread_ver_za16_s16(svint16_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8i16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_ver_za16_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_ver_za16_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_ver_za16, _s16, _m)(zd, pg, 1, slice); } @@ -986,7 +986,7 @@ svint16_t test_svread_ver_za16_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_ver_za32_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_ver_za32_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za32, _s32, _m)(zd, pg, 0, slice_base); } @@ -1006,7 +1006,7 @@ svint32_t test_svread_ver_za32_s32(svint32_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv4i32( [[ZD]], [[TMP0]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_ver_za32_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_ver_za32_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; return SME_ACLE_FUNC(svread_ver_za32, _s32, _m)(zd, pg, 3, slice); } @@ -1025,7 +1025,7 @@ svint32_t test_svread_ver_za32_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_ver_za64_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_ver_za64_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za64, _s64, _m)(zd, pg, 0, slice_base); } @@ -1045,7 +1045,7 @@ svint64_t test_svread_ver_za64_s64(svint64_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv2i64( [[ZD]], [[TMP0]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_ver_za64_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_ver_za64_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; return SME_ACLE_FUNC(svread_ver_za64, _s64, _m)(zd, pg, 7, slice); } @@ -1062,7 +1062,7 @@ svint64_t test_svread_ver_za64_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_ver_za8_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_ver_za8_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za8, _u8, _m)(zd, pg, 0, slice_base); } @@ -1080,7 +1080,7 @@ svuint8_t test_svread_ver_za8_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_ver_za8_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_ver_za8_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; return SME_ACLE_FUNC(svread_ver_za8, _u8, _m)(zd, pg, 0, slice); } @@ -1099,7 +1099,7 @@ svuint8_t test_svread_ver_za8_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_ver_za16_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_ver_za16_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za16, _u16, _m)(zd, pg, 0, slice_base); } @@ -1119,7 +1119,7 @@ svuint16_t test_svread_ver_za16_u16(svuint16_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8i16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_ver_za16_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_ver_za16_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_ver_za16, _u16, _m)(zd, pg, 1, slice); } @@ -1138,7 +1138,7 @@ svuint16_t test_svread_ver_za16_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_ver_za32_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_ver_za32_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za32, _u32, _m)(zd, pg, 0, slice_base); } @@ -1158,7 +1158,7 @@ svuint32_t test_svread_ver_za32_u32(svuint32_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv4i32( [[ZD]], [[TMP0]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_ver_za32_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_ver_za32_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; return SME_ACLE_FUNC(svread_ver_za32, _u32, _m)(zd, pg, 3, slice); } @@ -1177,7 +1177,7 @@ svuint32_t test_svread_ver_za32_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_ver_za64_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_ver_za64_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za64, _u64, _m)(zd, pg, 0, slice_base); } @@ -1197,7 +1197,7 @@ svuint64_t test_svread_ver_za64_u64(svuint64_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv2i64( [[ZD]], [[TMP0]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_ver_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_ver_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; return SME_ACLE_FUNC(svread_ver_za64, _u64, _m)(zd, pg, 7, slice); } @@ -1216,7 +1216,7 @@ svuint64_t test_svread_ver_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8f16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_ver_za16_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_ver_za16_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za16, _f16, _m)(zd, pg, 0, slice_base); } @@ -1236,7 +1236,7 @@ svfloat16_t test_svread_ver_za16_f16(svfloat16_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8f16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_ver_za16_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_ver_za16_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_ver_za16, _f16, _m)(zd, pg, 1, slice); } @@ -1255,7 +1255,7 @@ svfloat16_t test_svread_ver_za16_f16_1(svfloat16_t zd, svbool_t pg, uint32_t sli // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8bf16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_ver_za16_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_ver_za16_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za16, _bf16, _m)(zd, pg, 0, slice_base); } @@ -1275,7 +1275,7 @@ svbfloat16_t test_svread_ver_za16_bf16(svbfloat16_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv8bf16( [[ZD]], [[TMP0]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_ver_za16_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_ver_za16_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; return SME_ACLE_FUNC(svread_ver_za16, _bf16, _m)(zd, pg, 1, slice); } @@ -1294,7 +1294,7 @@ svbfloat16_t test_svread_ver_za16_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv4f32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_ver_za32_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_ver_za32_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za32, _f32, _m)(zd, pg, 0, slice_base); } @@ -1314,7 +1314,7 @@ svfloat32_t test_svread_ver_za32_f32(svfloat32_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv4f32( [[ZD]], [[TMP0]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_ver_za32_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_ver_za32_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; return SME_ACLE_FUNC(svread_ver_za32, _f32, _m)(zd, pg, 3, slice); } @@ -1333,7 +1333,7 @@ svfloat32_t test_svread_ver_za32_f32_1(svfloat32_t zd, svbool_t pg, uint32_t sli // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv2f64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_ver_za64_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_ver_za64_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za64, _f64, _m)(zd, pg, 0, slice_base); } @@ -1353,7 +1353,7 @@ svfloat64_t test_svread_ver_za64_f64(svfloat64_t zd, svbool_t pg, uint32_t slice // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv2f64( [[ZD]], [[TMP0]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_ver_za64_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_ver_za64_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; return SME_ACLE_FUNC(svread_ver_za64, _f64, _m)(zd, pg, 7, slice); } @@ -1370,7 +1370,7 @@ svfloat64_t test_svread_ver_za64_f64_1(svfloat64_t zd, svbool_t pg, uint32_t sli // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_ver_za128_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_ver_za128_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s8, _m)(zd, pg, 0, slice_base); } @@ -1386,7 +1386,7 @@ svint8_t test_svread_ver_za128_s8(svint8_t zd, svbool_t pg, uint32_t slice_base) // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svint8_t test_svread_ver_za128_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) { +svint8_t test_svread_ver_za128_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s8, _m)(zd, pg, 15, slice_base); } @@ -1404,7 +1404,7 @@ svint8_t test_svread_ver_za128_s8_1(svint8_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_ver_za128_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_ver_za128_s16(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s16, _m)(zd, pg, 0, slice_base); } @@ -1422,7 +1422,7 @@ svint16_t test_svread_ver_za128_s16(svint16_t zd, svbool_t pg, uint32_t slice_ba // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8i16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint16_t test_svread_ver_za128_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) { +svint16_t test_svread_ver_za128_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s16, _m)(zd, pg, 15, slice_base); } @@ -1440,7 +1440,7 @@ svint16_t test_svread_ver_za128_s16_1(svint16_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_ver_za128_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_ver_za128_s32(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s32, _m)(zd, pg, 0, slice_base); } @@ -1458,7 +1458,7 @@ svint32_t test_svread_ver_za128_s32(svint32_t zd, svbool_t pg, uint32_t slice_ba // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv4i32( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint32_t test_svread_ver_za128_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) { +svint32_t test_svread_ver_za128_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s32, _m)(zd, pg, 15, slice_base); } @@ -1476,7 +1476,7 @@ svint32_t test_svread_ver_za128_s32_1(svint32_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_ver_za128_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_ver_za128_s64(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s64, _m)(zd, pg, 0, slice_base); } @@ -1494,7 +1494,7 @@ svint64_t test_svread_ver_za128_s64(svint64_t zd, svbool_t pg, uint32_t slice_ba // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv2i64( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svint64_t test_svread_ver_za128_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) { +svint64_t test_svread_ver_za128_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _s64, _m)(zd, pg, 15, slice_base); } @@ -1510,7 +1510,7 @@ svint64_t test_svread_ver_za128_s64_1(svint64_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_ver_za128_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_ver_za128_u8(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u8, _m)(zd, pg, 0, slice_base); } @@ -1526,7 +1526,7 @@ svuint8_t test_svread_ver_za128_u8(svuint8_t zd, svbool_t pg, uint32_t slice_bas // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP0]] // -svuint8_t test_svread_ver_za128_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) { +svuint8_t test_svread_ver_za128_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u8, _m)(zd, pg, 15, slice_base); } @@ -1544,7 +1544,7 @@ svuint8_t test_svread_ver_za128_u8_1(svuint8_t zd, svbool_t pg, uint32_t slice_b // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8i16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_ver_za128_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_ver_za128_u16(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u16, _m)(zd, pg, 0, slice_base); } @@ -1562,7 +1562,7 @@ svuint16_t test_svread_ver_za128_u16(svuint16_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8i16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint16_t test_svread_ver_za128_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) { +svuint16_t test_svread_ver_za128_u16_1(svuint16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u16, _m)(zd, pg, 15, slice_base); } @@ -1580,7 +1580,7 @@ svuint16_t test_svread_ver_za128_u16_1(svuint16_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv4i32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_ver_za128_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_ver_za128_u32(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u32, _m)(zd, pg, 0, slice_base); } @@ -1598,7 +1598,7 @@ svuint32_t test_svread_ver_za128_u32(svuint32_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv4i32( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint32_t test_svread_ver_za128_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) { +svuint32_t test_svread_ver_za128_u32_1(svuint32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u32, _m)(zd, pg, 15, slice_base); } @@ -1616,7 +1616,7 @@ svuint32_t test_svread_ver_za128_u32_1(svuint32_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv2i64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_ver_za128_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_ver_za128_u64(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u64, _m)(zd, pg, 0, slice_base); } @@ -1634,7 +1634,7 @@ svuint64_t test_svread_ver_za128_u64(svuint64_t zd, svbool_t pg, uint32_t slice_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv2i64( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svuint64_t test_svread_ver_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) { +svuint64_t test_svread_ver_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _u64, _m)(zd, pg, 15, slice_base); } @@ -1652,7 +1652,7 @@ svuint64_t test_svread_ver_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8f16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_ver_za128_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_ver_za128_f16(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _f16, _m)(zd, pg, 0, slice_base); } @@ -1670,7 +1670,7 @@ svfloat16_t test_svread_ver_za128_f16(svfloat16_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8f16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat16_t test_svread_ver_za128_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svfloat16_t test_svread_ver_za128_f16_1(svfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _f16, _m)(zd, pg, 15, slice_base); } @@ -1688,7 +1688,7 @@ svfloat16_t test_svread_ver_za128_f16_1(svfloat16_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8bf16( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_ver_za128_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_ver_za128_bf16(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _bf16, _m)(zd, pg, 0, slice_base); } @@ -1706,7 +1706,7 @@ svbfloat16_t test_svread_ver_za128_bf16(svbfloat16_t zd, svbool_t pg, uint32_t s // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv8bf16( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svbfloat16_t test_svread_ver_za128_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) { +svbfloat16_t test_svread_ver_za128_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _bf16, _m)(zd, pg, 15, slice_base); } @@ -1724,7 +1724,7 @@ svbfloat16_t test_svread_ver_za128_bf16_1(svbfloat16_t zd, svbool_t pg, uint32_t // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv4f32( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_ver_za128_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_ver_za128_f32(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _f32, _m)(zd, pg, 0, slice_base); } @@ -1742,7 +1742,7 @@ svfloat32_t test_svread_ver_za128_f32(svfloat32_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv4f32( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat32_t test_svread_ver_za128_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) { +svfloat32_t test_svread_ver_za128_f32_1(svfloat32_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _f32, _m)(zd, pg, 15, slice_base); } @@ -1760,7 +1760,7 @@ svfloat32_t test_svread_ver_za128_f32_1(svfloat32_t zd, svbool_t pg, uint32_t sl // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv2f64( [[ZD]], [[TMP0]], i32 0, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_ver_za128_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_ver_za128_f64(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _f64, _m)(zd, pg, 0, slice_base); } @@ -1778,7 +1778,7 @@ svfloat64_t test_svread_ver_za128_f64(svfloat64_t zd, svbool_t pg, uint32_t slic // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv2f64( [[ZD]], [[TMP0]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret [[TMP1]] // -svfloat64_t test_svread_ver_za128_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) { +svfloat64_t test_svread_ver_za128_f64_1(svfloat64_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_shared_za { return SME_ACLE_FUNC(svread_ver_za128, _f64, _m)(zd, pg, 15, slice_base); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1.c index 9ed158aedf7e3b319c7e5884285d33bddc27314d..98ebbefc2e74ccd10ac8adbb52653ae88322792d 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1.c @@ -22,7 +22,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[PTR]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_za8(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_hor_za8(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_hor_za8(0, slice_base, pg, ptr); svst1_hor_za8(0, slice_base + 15, pg, ptr); } @@ -45,7 +45,7 @@ void test_svst1_hor_za8(uint32_t slice_base, svbool_t pg, void *ptr) __arm_strea // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[PTR]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_za16(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_hor_za16(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_hor_za16(0, slice_base, pg, ptr); svst1_hor_za16(1, slice_base + 7, pg, ptr); } @@ -68,7 +68,7 @@ void test_svst1_hor_za16(uint32_t slice_base, svbool_t pg, void *ptr) __arm_stre // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[PTR]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_za32(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_hor_za32(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_hor_za32(0, slice_base, pg, ptr); svst1_hor_za32(3, slice_base + 3, pg, ptr); } @@ -91,7 +91,7 @@ void test_svst1_hor_za32(uint32_t slice_base, svbool_t pg, void *ptr) __arm_stre // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[PTR]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_za64(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_hor_za64(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_hor_za64(0, slice_base, pg, ptr); svst1_hor_za64(7, slice_base + 1, pg, ptr); } @@ -112,7 +112,7 @@ void test_svst1_hor_za64(uint32_t slice_base, svbool_t pg, void *ptr) __arm_stre // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[PTR]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_za128(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_hor_za128(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_hor_za128(0, slice_base, pg, ptr); svst1_hor_za128(15, slice_base, pg, ptr); } @@ -133,7 +133,7 @@ void test_svst1_hor_za128(uint32_t slice_base, svbool_t pg, void *ptr) __arm_str // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[PTR]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_za8(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_ver_za8(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_ver_za8(0, slice_base, pg, ptr); svst1_ver_za8(0, slice_base + 15, pg, ptr); } @@ -156,7 +156,7 @@ void test_svst1_ver_za8(uint32_t slice_base, svbool_t pg, void *ptr) __arm_strea // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[PTR]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_za16(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_ver_za16(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_ver_za16(0, slice_base, pg, ptr); svst1_ver_za16(1, slice_base + 7, pg, ptr); } @@ -179,7 +179,7 @@ void test_svst1_ver_za16(uint32_t slice_base, svbool_t pg, void *ptr) __arm_stre // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[PTR]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_za32(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_ver_za32(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_ver_za32(0, slice_base, pg, ptr); svst1_ver_za32(3, slice_base + 3, pg, ptr); } @@ -202,7 +202,7 @@ void test_svst1_ver_za32(uint32_t slice_base, svbool_t pg, void *ptr) __arm_stre // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[PTR]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_za64(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_ver_za64(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_ver_za64(0, slice_base, pg, ptr); svst1_ver_za64(7, slice_base + 1, pg, ptr); } @@ -223,7 +223,7 @@ void test_svst1_ver_za64(uint32_t slice_base, svbool_t pg, void *ptr) __arm_stre // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[PTR]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_za128(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming { +void test_svst1_ver_za128(uint32_t slice_base, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_ver_za128(0, slice_base, pg, ptr); svst1_ver_za128(15, slice_base, pg, ptr); } diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1_vnum.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1_vnum.c index 627098d9365bd43821ade095f07cb7656af5a1bf..938e62a15c7716ced2b3523645fe423f616922ca 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1_vnum.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_st1_vnum.c @@ -28,7 +28,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_hor_vnum_za8(0, slice_base, pg, ptr, vnum); svst1_hor_vnum_za8(0, slice_base + 15, pg, ptr, vnum); } @@ -57,7 +57,7 @@ void test_svst1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_hor_vnum_za16(0, slice_base, pg, ptr, vnum); svst1_hor_vnum_za16(1, slice_base + 7, pg, ptr, vnum); } @@ -86,7 +86,7 @@ void test_svst1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_hor_vnum_za32(0, slice_base, pg, ptr, vnum); svst1_hor_vnum_za32(3, slice_base + 3, pg, ptr, vnum); } @@ -115,7 +115,7 @@ void test_svst1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_hor_vnum_za64(0, slice_base, pg, ptr, vnum); svst1_hor_vnum_za64(7, slice_base + 1, pg, ptr, vnum); } @@ -142,7 +142,7 @@ void test_svst1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_hor_vnum_za128(0, slice_base, pg, ptr, vnum); svst1_hor_vnum_za128(15, slice_base, pg, ptr, vnum); } @@ -169,7 +169,7 @@ void test_svst1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int6 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_ver_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_ver_vnum_za8(0, slice_base, pg, ptr, vnum); svst1_ver_vnum_za8(0, slice_base + 15, pg, ptr, vnum); } @@ -198,7 +198,7 @@ void test_svst1_ver_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_ver_vnum_za16(0, slice_base, pg, ptr, vnum); svst1_ver_vnum_za16(1, slice_base + 7, pg, ptr, vnum); } @@ -227,7 +227,7 @@ void test_svst1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_ver_vnum_za32(0, slice_base, pg, ptr, vnum); svst1_ver_vnum_za32(3, slice_base + 3, pg, ptr, vnum); } @@ -256,7 +256,7 @@ void test_svst1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_ver_vnum_za64(0, slice_base, pg, ptr, vnum); svst1_ver_vnum_za64(7, slice_base + 1, pg, ptr, vnum); } @@ -283,7 +283,7 @@ void test_svst1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) // CHECK-CXX-NEXT: ret void // -void test_svst1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming { +void test_svst1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_shared_za { svst1_ver_vnum_za128(0, slice_base, pg, ptr, vnum); svst1_ver_vnum_za128(15, slice_base, pg, ptr, vnum); } diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c new file mode 100644 index 0000000000000000000000000000000000000000..282819c8ca3501ad21e76d9727b80786b6bcba4f --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c @@ -0,0 +1,72 @@ +// 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 -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -S -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +#include + +// CHECK-LABEL: @test_in_streaming_mode( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call aarch64_sme_preservemost_from_x2 { i64, i64 } @__arm_sme_state() #[[ATTR3:[0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i64 } [[TMP0]], 0 +// CHECK-NEXT: [[AND_I:%.*]] = and i64 [[TMP1]], 1 +// CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp ne i64 [[AND_I]], 0 +// CHECK-NEXT: ret i1 [[TOBOOL_I]] +// +// CPP-CHECK-LABEL: @_Z22test_in_streaming_modev( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call aarch64_sme_preservemost_from_x2 { i64, i64 } @__arm_sme_state() #[[ATTR3:[0-9]+]] +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i64 } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[AND_I:%.*]] = and i64 [[TMP1]], 1 +// CPP-CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp ne i64 [[AND_I]], 0 +// CPP-CHECK-NEXT: ret i1 [[TOBOOL_I]] +// +bool test_in_streaming_mode(void) __arm_streaming_compatible { + return __arm_in_streaming_mode(); +} + +// CHECK-LABEL: @test_za_disable( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @__arm_za_disable() #[[ATTR4:[0-9]+]] +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_za_disablev( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @__arm_za_disable() #[[ATTR4:[0-9]+]] +// CPP-CHECK-NEXT: ret void +// +void test_za_disable(void) __arm_streaming_compatible { + __arm_za_disable(); +} + +// CHECK-LABEL: @test_has_sme( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call aarch64_sme_preservemost_from_x2 { i64, i64 } @__arm_sme_state() #[[ATTR3]] +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i64 } [[TMP0]], 0 +// CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp slt i64 [[TMP1]], 0 +// CHECK-NEXT: ret i1 [[TOBOOL_I]] +// +// CPP-CHECK-LABEL: @_Z12test_has_smev( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call aarch64_sme_preservemost_from_x2 { i64, i64 } @__arm_sme_state() #[[ATTR3]] +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i64 } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp slt i64 [[TMP1]], 0 +// CPP-CHECK-NEXT: ret i1 [[TOBOOL_I]] +// +bool test_has_sme(void) __arm_streaming_compatible { + return __arm_has_sme(); +} + +// CHECK-LABEL: @test_svundef_za( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svundef_zav( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: ret void +// +void test_svundef_za(void) __arm_streaming_compatible __arm_shared_za { + svundef_za(); +} + diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_str.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_str.c index baadfc18563a005b58e8519b8e12db33bcd9d201..bcf368bc8dce464d7193344485179ba4b45bc8c2 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_str.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_str.c @@ -12,7 +12,7 @@ // CHECK-NEXT: tail call void @llvm.aarch64.sme.str(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_svstr_vnum_za(uint32_t slice_base, void *ptr) { +void test_svstr_vnum_za(uint32_t slice_base, void *ptr) __arm_shared_za { svstr_vnum_za(slice_base, ptr, 0); } @@ -22,7 +22,7 @@ void test_svstr_vnum_za(uint32_t slice_base, void *ptr) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.str(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 15) // CHECK-NEXT: ret void // -void test_svstr_vnum_za_1(uint32_t slice_base, void *ptr) { +void test_svstr_vnum_za_1(uint32_t slice_base, void *ptr) __arm_shared_za { svstr_vnum_za(slice_base, ptr, 15); } @@ -32,7 +32,7 @@ void test_svstr_vnum_za_1(uint32_t slice_base, void *ptr) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.str(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 0) // CHECK-NEXT: ret void // -void test_svstr_za(uint32_t slice_base, void *ptr) { +void test_svstr_za(uint32_t slice_base, void *ptr) __arm_shared_za { svstr_za(slice_base, ptr); } @@ -43,7 +43,7 @@ void test_svstr_za(uint32_t slice_base, void *ptr) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.str(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 [[TMP0:%.*]]) // CHECK-NEXT: ret void // -void test_svstr_vnum_za_var(uint32_t slice_base, void *ptr, int64_t vnum) { +void test_svstr_vnum_za_var(uint32_t slice_base, void *ptr, int64_t vnum) __arm_shared_za { svstr_vnum_za(slice_base, ptr, vnum); } @@ -53,6 +53,6 @@ void test_svstr_vnum_za_var(uint32_t slice_base, void *ptr, int64_t vnum) { // CHECK-NEXT: tail call void @llvm.aarch64.sme.str(i32 [[SLICE_BASE:%.*]], ptr [[PTR:%.*]], i32 16) // CHECK-NEXT: ret void // -void test_svstr_vnum_za_2(uint32_t slice_base, void *ptr) { +void test_svstr_vnum_za_2(uint32_t slice_base, void *ptr) __arm_shared_za { svstr_vnum_za(slice_base, ptr, 16); } diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_write.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_write.c index 3f11aa8c5eb2e7c2911641742047d9813587496d..38c8402c3d0fa7e95c8bf2011ab027c73967ee5a 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_write.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_write.c @@ -26,7 +26,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za8_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_hor_za8_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za8, _s8, _m)(0, slice_base, pg, zn); } @@ -44,7 +44,7 @@ void test_svwrite_hor_za8_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za8_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_hor_za8_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; SME_ACLE_FUNC(svwrite_hor_za8, _s8, _m)(0, slice, pg, zn); } @@ -63,7 +63,7 @@ void test_svwrite_hor_za8_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_hor_za16_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za16, _s16, _m)(0, slice_base, pg, zn); } @@ -83,7 +83,7 @@ void test_svwrite_hor_za16_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8i16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_hor_za16_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_hor_za16, _s16, _m)(1, slice, pg, zn); } @@ -102,7 +102,7 @@ void test_svwrite_hor_za16_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za32_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_hor_za32_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za32, _s32, _m)(0, slice_base, pg, zn); } @@ -122,7 +122,7 @@ void test_svwrite_hor_za32_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv4i32(i32 3, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za32_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_hor_za32_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; SME_ACLE_FUNC(svwrite_hor_za32, _s32, _m)(3, slice, pg, zn); } @@ -141,7 +141,7 @@ void test_svwrite_hor_za32_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za64_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_hor_za64_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za64, _s64, _m)(0, slice_base, pg, zn); } @@ -161,7 +161,7 @@ void test_svwrite_hor_za64_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv2i64(i32 7, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za64_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_hor_za64_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; SME_ACLE_FUNC(svwrite_hor_za64, _s64, _m)(7, slice, pg, zn); } @@ -178,7 +178,7 @@ void test_svwrite_hor_za64_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za8_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_hor_za8_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za8, _u8, _m)(0, slice_base, pg, zn); } @@ -196,7 +196,7 @@ void test_svwrite_hor_za8_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za8_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_hor_za8_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; SME_ACLE_FUNC(svwrite_hor_za8, _u8, _m)(0, slice, pg, zn); } @@ -215,7 +215,7 @@ void test_svwrite_hor_za8_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_hor_za16_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za16, _u16, _m)(0, slice_base, pg, zn); } @@ -235,7 +235,7 @@ void test_svwrite_hor_za16_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8i16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_hor_za16_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_hor_za16, _u16, _m)(1, slice, pg, zn); } @@ -254,7 +254,7 @@ void test_svwrite_hor_za16_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za32_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_hor_za32_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za32, _u32, _m)(0, slice_base, pg, zn); } @@ -274,7 +274,7 @@ void test_svwrite_hor_za32_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv4i32(i32 3, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za32_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_hor_za32_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; SME_ACLE_FUNC(svwrite_hor_za32, _u32, _m)(3, slice, pg, zn); } @@ -293,7 +293,7 @@ void test_svwrite_hor_za32_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za64_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_hor_za64_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za64, _u64, _m)(0, slice_base, pg, zn); } @@ -313,7 +313,7 @@ void test_svwrite_hor_za64_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv2i64(i32 7, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_hor_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; SME_ACLE_FUNC(svwrite_hor_za64, _u64, _m)(7, slice, pg, zn); } @@ -332,7 +332,7 @@ void test_svwrite_hor_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8f16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_hor_za16_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za16, _f16, _m)(0, slice_base, pg, zn); } @@ -352,7 +352,7 @@ void test_svwrite_hor_za16_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8f16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_hor_za16_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_hor_za16, _f16, _m)(1, slice, pg, zn); } @@ -371,7 +371,7 @@ void test_svwrite_hor_za16_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8bf16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_hor_za16_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za16, _bf16, _m)(0, slice_base, pg, zn); } @@ -391,7 +391,7 @@ void test_svwrite_hor_za16_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv8bf16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za16_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_hor_za16_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_hor_za16, _bf16, _m)(1, slice, pg, zn); } @@ -410,7 +410,7 @@ void test_svwrite_hor_za16_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv4f32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za32_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_hor_za32_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za32, _f32, _m)(0, slice_base, pg, zn); } @@ -430,7 +430,7 @@ void test_svwrite_hor_za32_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv4f32(i32 3, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za32_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_hor_za32_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; SME_ACLE_FUNC(svwrite_hor_za32, _f32, _m)(3, slice, pg, zn); } @@ -449,7 +449,7 @@ void test_svwrite_hor_za32_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv2f64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za64_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_hor_za64_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za64, _f64, _m)(0, slice_base, pg, zn); } @@ -469,7 +469,7 @@ void test_svwrite_hor_za64_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv2f64(i32 7, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za64_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_hor_za64_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; SME_ACLE_FUNC(svwrite_hor_za64, _f64, _m)(7, slice, pg, zn); } @@ -486,7 +486,7 @@ void test_svwrite_hor_za64_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_hor_za128_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s8, _m)(0, slice_base, pg, zn); } @@ -502,7 +502,7 @@ void test_svwrite_hor_za128_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_hor_za128_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s8, _m)(15, slice_base, pg, zn); } @@ -520,7 +520,7 @@ void test_svwrite_hor_za128_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_hor_za128_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s16, _m)(0, slice_base, pg, zn); } @@ -538,7 +538,7 @@ void test_svwrite_hor_za128_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8i16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_hor_za128_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s16, _m)(15, slice_base, pg, zn); } @@ -556,7 +556,7 @@ void test_svwrite_hor_za128_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_hor_za128_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s32, _m)(0, slice_base, pg, zn); } @@ -574,7 +574,7 @@ void test_svwrite_hor_za128_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv4i32(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_hor_za128_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s32, _m)(15, slice_base, pg, zn); } @@ -592,7 +592,7 @@ void test_svwrite_hor_za128_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_hor_za128_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s64, _m)(0, slice_base, pg, zn); } @@ -610,7 +610,7 @@ void test_svwrite_hor_za128_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv2i64(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_hor_za128_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _s64, _m)(15, slice_base, pg, zn); } @@ -626,7 +626,7 @@ void test_svwrite_hor_za128_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_hor_za128_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u8, _m)(0, slice_base, pg, zn); } @@ -642,7 +642,7 @@ void test_svwrite_hor_za128_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_hor_za128_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u8, _m)(15, slice_base, pg, zn); } @@ -660,7 +660,7 @@ void test_svwrite_hor_za128_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_hor_za128_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u16, _m)(0, slice_base, pg, zn); } @@ -678,7 +678,7 @@ void test_svwrite_hor_za128_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8i16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_hor_za128_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u16, _m)(15, slice_base, pg, zn); } @@ -696,7 +696,7 @@ void test_svwrite_hor_za128_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_hor_za128_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u32, _m)(0, slice_base, pg, zn); } @@ -714,7 +714,7 @@ void test_svwrite_hor_za128_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv4i32(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_hor_za128_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u32, _m)(15, slice_base, pg, zn); } @@ -732,7 +732,7 @@ void test_svwrite_hor_za128_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_hor_za128_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u64, _m)(0, slice_base, pg, zn); } @@ -750,7 +750,7 @@ void test_svwrite_hor_za128_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv2i64(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_hor_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _u64, _m)(15, slice_base, pg, zn); } @@ -768,7 +768,7 @@ void test_svwrite_hor_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8f16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_hor_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _f16, _m)(0, slice_base, pg, zn); } @@ -786,7 +786,7 @@ void test_svwrite_hor_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8f16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_hor_za128_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _f16, _m)(15, slice_base, pg, zn); } @@ -804,7 +804,7 @@ void test_svwrite_hor_za128_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8bf16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_hor_za128_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _bf16, _m)(0, slice_base, pg, zn); } @@ -822,7 +822,7 @@ void test_svwrite_hor_za128_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv8bf16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_hor_za128_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _bf16, _m)(15, slice_base, pg, zn); } @@ -840,7 +840,7 @@ void test_svwrite_hor_za128_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv4f32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_hor_za128_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _f32, _m)(0, slice_base, pg, zn); } @@ -858,7 +858,7 @@ void test_svwrite_hor_za128_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv4f32(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_hor_za128_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _f32, _m)(15, slice_base, pg, zn); } @@ -876,7 +876,7 @@ void test_svwrite_hor_za128_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv2f64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_hor_za128_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _f64, _m)(0, slice_base, pg, zn); } @@ -894,7 +894,7 @@ void test_svwrite_hor_za128_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv2f64(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_hor_za128_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_hor_za128_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_hor_za128, _f64, _m)(15, slice_base, pg, zn); } @@ -910,7 +910,7 @@ void test_svwrite_hor_za128_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za8_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_ver_za8_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za8, _s8, _m)(0, slice_base, pg, zn); } @@ -928,7 +928,7 @@ void test_svwrite_ver_za8_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za8_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_ver_za8_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; SME_ACLE_FUNC(svwrite_ver_za8, _s8, _m)(0, slice, pg, zn); } @@ -947,7 +947,7 @@ void test_svwrite_ver_za8_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_ver_za16_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za16, _s16, _m)(0, slice_base, pg, zn); } @@ -967,7 +967,7 @@ void test_svwrite_ver_za16_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8i16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_ver_za16_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_ver_za16, _s16, _m)(1, slice, pg, zn); } @@ -986,7 +986,7 @@ void test_svwrite_ver_za16_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za32_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_ver_za32_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za32, _s32, _m)(0, slice_base, pg, zn); } @@ -1006,7 +1006,7 @@ void test_svwrite_ver_za32_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv4i32(i32 3, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za32_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_ver_za32_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; SME_ACLE_FUNC(svwrite_ver_za32, _s32, _m)(3, slice, pg, zn); } @@ -1025,7 +1025,7 @@ void test_svwrite_ver_za32_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za64_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_ver_za64_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za64, _s64, _m)(0, slice_base, pg, zn); } @@ -1045,7 +1045,7 @@ void test_svwrite_ver_za64_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv2i64(i32 7, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za64_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_ver_za64_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; SME_ACLE_FUNC(svwrite_ver_za64, _s64, _m)(7, slice, pg, zn); } @@ -1062,7 +1062,7 @@ void test_svwrite_ver_za64_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za8_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_ver_za8_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za8, _u8, _m)(0, slice_base, pg, zn); } @@ -1080,7 +1080,7 @@ void test_svwrite_ver_za8_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za8_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_ver_za8_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 15; SME_ACLE_FUNC(svwrite_ver_za8, _u8, _m)(0, slice, pg, zn); } @@ -1099,7 +1099,7 @@ void test_svwrite_ver_za8_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_ver_za16_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za16, _u16, _m)(0, slice_base, pg, zn); } @@ -1119,7 +1119,7 @@ void test_svwrite_ver_za16_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8i16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_ver_za16_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_ver_za16, _u16, _m)(1, slice, pg, zn); } @@ -1138,7 +1138,7 @@ void test_svwrite_ver_za16_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za32_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_ver_za32_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za32, _u32, _m)(0, slice_base, pg, zn); } @@ -1158,7 +1158,7 @@ void test_svwrite_ver_za32_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv4i32(i32 3, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za32_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_ver_za32_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; SME_ACLE_FUNC(svwrite_ver_za32, _u32, _m)(3, slice, pg, zn); } @@ -1177,7 +1177,7 @@ void test_svwrite_ver_za32_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za64_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_ver_za64_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za64, _u64, _m)(0, slice_base, pg, zn); } @@ -1197,7 +1197,7 @@ void test_svwrite_ver_za64_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv2i64(i32 7, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_ver_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; SME_ACLE_FUNC(svwrite_ver_za64, _u64, _m)(7, slice, pg, zn); } @@ -1216,7 +1216,7 @@ void test_svwrite_ver_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8f16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_ver_za16_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za16, _f16, _m)(0, slice_base, pg, zn); } @@ -1236,7 +1236,7 @@ void test_svwrite_ver_za16_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8f16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_ver_za16_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_ver_za16, _f16, _m)(1, slice, pg, zn); } @@ -1255,7 +1255,7 @@ void test_svwrite_ver_za16_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8bf16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_ver_za16_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za16, _bf16, _m)(0, slice_base, pg, zn); } @@ -1275,7 +1275,7 @@ void test_svwrite_ver_za16_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv8bf16(i32 1, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za16_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_ver_za16_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 7; SME_ACLE_FUNC(svwrite_ver_za16, _bf16, _m)(1, slice, pg, zn); } @@ -1294,7 +1294,7 @@ void test_svwrite_ver_za16_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv4f32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za32_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_ver_za32_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za32, _f32, _m)(0, slice_base, pg, zn); } @@ -1314,7 +1314,7 @@ void test_svwrite_ver_za32_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv4f32(i32 3, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za32_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_ver_za32_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 3; SME_ACLE_FUNC(svwrite_ver_za32, _f32, _m)(3, slice, pg, zn); } @@ -1333,7 +1333,7 @@ void test_svwrite_ver_za32_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv2f64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za64_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_ver_za64_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za64, _f64, _m)(0, slice_base, pg, zn); } @@ -1353,7 +1353,7 @@ void test_svwrite_ver_za64_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv2f64(i32 7, i32 [[ADD]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za64_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_ver_za64_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { uint32_t slice = slice_base + 1; SME_ACLE_FUNC(svwrite_ver_za64, _f64, _m)(7, slice, pg, zn); } @@ -1370,7 +1370,7 @@ void test_svwrite_ver_za64_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_ver_za128_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s8, _m)(0, slice_base, pg, zn); } @@ -1386,7 +1386,7 @@ void test_svwrite_ver_za128_s8(uint32_t slice_base, svbool_t pg, svint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) { +void test_svwrite_ver_za128_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s8, _m)(15, slice_base, pg, zn); } @@ -1404,7 +1404,7 @@ void test_svwrite_ver_za128_s8_1(uint32_t slice_base, svbool_t pg, svint8_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_ver_za128_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s16, _m)(0, slice_base, pg, zn); } @@ -1422,7 +1422,7 @@ void test_svwrite_ver_za128_s16(uint32_t slice_base, svbool_t pg, svint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8i16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) { +void test_svwrite_ver_za128_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s16, _m)(15, slice_base, pg, zn); } @@ -1440,7 +1440,7 @@ void test_svwrite_ver_za128_s16_1(uint32_t slice_base, svbool_t pg, svint16_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_ver_za128_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s32, _m)(0, slice_base, pg, zn); } @@ -1458,7 +1458,7 @@ void test_svwrite_ver_za128_s32(uint32_t slice_base, svbool_t pg, svint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv4i32(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) { +void test_svwrite_ver_za128_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s32, _m)(15, slice_base, pg, zn); } @@ -1476,7 +1476,7 @@ void test_svwrite_ver_za128_s32_1(uint32_t slice_base, svbool_t pg, svint32_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_ver_za128_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s64, _m)(0, slice_base, pg, zn); } @@ -1494,7 +1494,7 @@ void test_svwrite_ver_za128_s64(uint32_t slice_base, svbool_t pg, svint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv2i64(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) { +void test_svwrite_ver_za128_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _s64, _m)(15, slice_base, pg, zn); } @@ -1510,7 +1510,7 @@ void test_svwrite_ver_za128_s64_1(uint32_t slice_base, svbool_t pg, svint64_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_ver_za128_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u8, _m)(0, slice_base, pg, zn); } @@ -1526,7 +1526,7 @@ void test_svwrite_ver_za128_u8(uint32_t slice_base, svbool_t pg, svuint8_t zn) { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) { +void test_svwrite_ver_za128_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u8, _m)(15, slice_base, pg, zn); } @@ -1544,7 +1544,7 @@ void test_svwrite_ver_za128_u8_1(uint32_t slice_base, svbool_t pg, svuint8_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8i16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_ver_za128_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u16, _m)(0, slice_base, pg, zn); } @@ -1562,7 +1562,7 @@ void test_svwrite_ver_za128_u16(uint32_t slice_base, svbool_t pg, svuint16_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8i16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) { +void test_svwrite_ver_za128_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u16, _m)(15, slice_base, pg, zn); } @@ -1580,7 +1580,7 @@ void test_svwrite_ver_za128_u16_1(uint32_t slice_base, svbool_t pg, svuint16_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv4i32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_ver_za128_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u32, _m)(0, slice_base, pg, zn); } @@ -1598,7 +1598,7 @@ void test_svwrite_ver_za128_u32(uint32_t slice_base, svbool_t pg, svuint32_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv4i32(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) { +void test_svwrite_ver_za128_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u32, _m)(15, slice_base, pg, zn); } @@ -1616,7 +1616,7 @@ void test_svwrite_ver_za128_u32_1(uint32_t slice_base, svbool_t pg, svuint32_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv2i64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_ver_za128_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u64, _m)(0, slice_base, pg, zn); } @@ -1634,7 +1634,7 @@ void test_svwrite_ver_za128_u64(uint32_t slice_base, svbool_t pg, svuint64_t zn) // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv2i64(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) { +void test_svwrite_ver_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _u64, _m)(15, slice_base, pg, zn); } @@ -1652,7 +1652,7 @@ void test_svwrite_ver_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t z // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8f16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_ver_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _f16, _m)(0, slice_base, pg, zn); } @@ -1670,7 +1670,7 @@ void test_svwrite_ver_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8f16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) { +void test_svwrite_ver_za128_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _f16, _m)(15, slice_base, pg, zn); } @@ -1688,7 +1688,7 @@ void test_svwrite_ver_za128_f16_1(uint32_t slice_base, svbool_t pg, svfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8bf16(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_ver_za128_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _bf16, _m)(0, slice_base, pg, zn); } @@ -1706,7 +1706,7 @@ void test_svwrite_ver_za128_bf16(uint32_t slice_base, svbool_t pg, svbfloat16_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv8bf16(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) { +void test_svwrite_ver_za128_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _bf16, _m)(15, slice_base, pg, zn); } @@ -1724,7 +1724,7 @@ void test_svwrite_ver_za128_bf16_1(uint32_t slice_base, svbool_t pg, svbfloat16_ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv4f32(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_ver_za128_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _f32, _m)(0, slice_base, pg, zn); } @@ -1742,7 +1742,7 @@ void test_svwrite_ver_za128_f32(uint32_t slice_base, svbool_t pg, svfloat32_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv4f32(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) { +void test_svwrite_ver_za128_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _f32, _m)(15, slice_base, pg, zn); } @@ -1760,7 +1760,7 @@ void test_svwrite_ver_za128_f32_1(uint32_t slice_base, svbool_t pg, svfloat32_t // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv2f64(i32 0, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_ver_za128_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _f64, _m)(0, slice_base, pg, zn); } @@ -1778,7 +1778,7 @@ void test_svwrite_ver_za128_f64(uint32_t slice_base, svbool_t pg, svfloat64_t zn // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv2f64(i32 15, i32 [[SLICE_BASE]], [[TMP0]], [[ZN]]) // CHECK-CXX-NEXT: ret void // -void test_svwrite_ver_za128_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) { +void test_svwrite_ver_za128_f64_1(uint32_t slice_base, svbool_t pg, svfloat64_t zn) __arm_streaming __arm_shared_za { SME_ACLE_FUNC(svwrite_ver_za128, _f64, _m)(15, slice_base, pg, zn); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c index 750eead7c705e2f5364a8ead60b91adc6a199f96..ddd960236953892d29ddaa8c403117a34fbd994a 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c @@ -18,7 +18,7 @@ // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.zero(i32 0) // CHECK-CXX-NEXT: ret void // -void test_svzero_mask_za() { +void test_svzero_mask_za(void) __arm_shared_za { svzero_mask_za(0); } @@ -34,7 +34,7 @@ void test_svzero_mask_za() { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.zero(i32 176) // CHECK-CXX-NEXT: ret void // -void test_svzero_mask_za_1() { +void test_svzero_mask_za_1(void) __arm_shared_za { svzero_mask_za(176); } @@ -50,7 +50,7 @@ void test_svzero_mask_za_1() { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255) // CHECK-CXX-NEXT: ret void // -void test_svzero_mask_za_2() { +void test_svzero_mask_za_2(void) __arm_shared_za { svzero_mask_za(255); } @@ -66,7 +66,7 @@ void test_svzero_mask_za_2() { // CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255) // CHECK-CXX-NEXT: ret void // -void test_svzero_za() { +void test_svzero_za(void) __arm_shared_za { svzero_za(); } //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_cvtn.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_cvtn.c index 84aa6764ba380a6471b3b17ddcb115640e1d1344..a865fd1bd5f5fb18f51a37e960c55999f88533ed 100644 --- a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_cvtn.c +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_cvtn.c @@ -53,60 +53,6 @@ svbfloat16_t test_cvtn_bf16_x2(svfloat32x2_t zn) __arm_streaming { return SVE_ACLE_FUNC(svcvtn_bf16,_f32_x2,,)(zn); } -// CHECK-LABEL: @test_qcvtn_s16_s32_x2( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) -// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) -// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) -// CHECK-NEXT: ret [[TMP2]] -// -// CPP-CHECK-LABEL: @_Z21test_qcvtn_s16_s32_x211svint32x2_t( -// CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) -// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) -// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) -// CPP-CHECK-NEXT: ret [[TMP2]] -// -svint16_t test_qcvtn_s16_s32_x2(svint32x2_t zn) __arm_streaming_compatible { - return SVE_ACLE_FUNC(svqcvtn_s16,_s32_x2,,)(zn); -} - -// CHECK-LABEL: @test_qcvtn_u16_u32_x2( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) -// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) -// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.uqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) -// CHECK-NEXT: ret [[TMP2]] -// -// CPP-CHECK-LABEL: @_Z21test_qcvtn_u16_u32_x212svuint32x2_t( -// CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) -// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) -// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.uqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) -// CPP-CHECK-NEXT: ret [[TMP2]] -// -svuint16_t test_qcvtn_u16_u32_x2(svuint32x2_t zn) __arm_streaming_compatible { - return SVE_ACLE_FUNC(svqcvtn_u16,_u32_x2,,)(zn); -} - -// CHECK-LABEL: @test_qcvtn_u16_s32_x2( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) -// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) -// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtun.x2.nxv4i32( [[TMP0]], [[TMP1]]) -// CHECK-NEXT: ret [[TMP2]] -// -// CPP-CHECK-LABEL: @_Z21test_qcvtn_u16_s32_x211svint32x2_t( -// CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) -// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) -// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtun.x2.nxv4i32( [[TMP0]], [[TMP1]]) -// CPP-CHECK-NEXT: ret [[TMP2]] -// -svuint16_t test_qcvtn_u16_s32_x2(svint32x2_t zn) __arm_streaming_compatible { - return SVE_ACLE_FUNC(svqcvtn_u16,_s32_x2,,)(zn); -} - // CHECK-LABEL: @test_qcvtn_u8_u32_x4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_fp_dots.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_fp_dots.c new file mode 100644 index 0000000000000000000000000000000000000000..ff4176530710af5934be6798bc3a7f19fb3baeb1 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_fp_dots.c @@ -0,0 +1,297 @@ +// 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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Multi, multi (half) +// CHECK-LABEL: @test_svdot_multi_za32_vg1x2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fdot.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za32_vg1x2_f16j13svfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fdot.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_f16,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fdot.za32.vg1x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za32_vg1x4_f16j13svfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fdot.za32.vg1x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_f16,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, single (half) +// CHECK-LABEL: @test_svdot_single_za32_vg1x2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za32_vg1x2_f16j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_f16,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za32_vg1x4_f16j13svfloat16x4_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_f16,,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, indexed (half) +// CHECK-LABEL: @test_svdot_lane_za32_vg1x2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za32_vg1x2_f16j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,,_f16,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za32_vg1x4_f16j13svfloat16x4_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,,_f16,_vg1x4)(slice_base, zn, zm, 3); +} + + +// +// Multi, multi (bfloat) +// CHECK-LABEL: @test_svdot_multi_za32_vg1x2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_multi_za32_vg1x2_bf16j14svbfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_bf16,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.za32.vg1x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_multi_za32_vg1x4_bf16j14svbfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.za32.vg1x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_bf16,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, single (bfloat) +// CHECK-LABEL: @test_svdot_single_za32_vg1x2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z33test_svdot_single_za32_vg1x2_bf16j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_bf16,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z33test_svdot_single_za32_vg1x4_bf16j14svbfloat16x4_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.single.za32.vg1x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_bf16,,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, indexed (bfloat) +// CHECK-LABEL: @test_svdot_lane_za32_vg1x2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_lane_za32_vg1x2_bf16j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,_bf16,,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_lane_za32_vg1x4_bf16j14svbfloat16x4_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fdot.lane.za32.vg1x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,_bf16,,_vg1x4)(slice_base, zn, zm, 3); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_frint.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_frint.c new file mode 100644 index 0000000000000000000000000000000000000000..2a34b0e2878ef9a1a76c153b74672063a415cb9e --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_frint.c @@ -0,0 +1,282 @@ +// 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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -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 + +// FRINTA + +// CHECK-LABEL: @test_svfrinta_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frinta.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrinta_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frinta.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svfrinta_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrinta,_f32_x2)(zn); +} + +// CHECK-LABEL: @test_svfrinta_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frinta.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrinta_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frinta.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svfrinta_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrinta,_f32_x4)(zn); +} + +// FRINTM + +// CHECK-LABEL: @test_svfrintam_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frintm.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z21test_svfrintam_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frintm.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svfrintam_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrintm,_f32_x2)(zn); +} + +// CHECK-LABEL: @test_svfrintm_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frintm.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrintm_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frintm.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svfrintm_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrintm,_f32_x4)(zn); +} + +// FRINTN + +// CHECK-LABEL: @test_svfrintn_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frintn.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrintn_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frintn.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svfrintn_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrintn,_f32_x2)(zn); +} + +// CHECK-LABEL: @test_svfrintn_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frintn.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrintn_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frintn.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svfrintn_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrintn,_f32_x4)(zn); +} + +// FRINTP + +// CHECK-LABEL: @test_svfrintp_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frintp.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrintp_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.frintp.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svfrintp_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrintp,_f32_x2)(zn); +} + +// CHECK-LABEL: @test_svfrintp_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frintp.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z20test_svfrintp_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.frintp.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svfrintp_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svrintp,_f32_x4)(zn); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_int_dots.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_int_dots.c new file mode 100644 index 0000000000000000000000000000000000000000..0d85071b7fc3e624570ce224e5e7ba8db8e68459 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_int_dots.c @@ -0,0 +1,1103 @@ +// 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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -target-feature +sme-i16i64 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Multi, multi (unsigned) +// CHECK-LABEL: @test_svdot_multi_za32_vg1x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za32_vg1x2_u16j12svuint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_u16,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za32_vg1x4_u16j12svuint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_u16,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_multi_za32_vg1x2_u8j11svuint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_u8,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_multi_za32_vg1x4_u8j11svuint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_u8,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za64_vg1x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za64_vg1x2_u16j12svuint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za64_vg1x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za64,,,_u16,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za64_vg1x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za64_vg1x4_u16j12svuint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za64_vg1x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za64,,,_u16,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, multi (signed) +// CHECK-LABEL: @test_svdot_multi_za32_vg1x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za32_vg1x2_s16j11svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x2_s16(uint32_t slice_base, svint16x2_t zn, svint16x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_s16,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za32_vg1x4_s16j11svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x4_s16(uint32_t slice_base, svint16x4_t zn, svint16x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_s16,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_multi_za32_vg1x2_s8j10svint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x2_s8(uint32_t slice_base, svint8x2_t zn, svint8x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_s8,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za32_vg1x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_multi_za32_vg1x4_s8j10svint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_vg1x4_s8(uint32_t slice_base, svint8x4_t zn, svint8x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za32,,,_s8,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za64_vg1x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za64_vg1x2_s16j11svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za64_vg1x2_s16(uint32_t slice_base, svint16x2_t zn, svint16x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za64,,,_s16,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_multi_za64_vg1x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_multi_za64_vg1x4_s16j11svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za64_vg1x4_s16(uint32_t slice_base, svint16x4_t zn, svint16x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_za64,,,_s16,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, single (unsigned) +// CHECK-LABEL: @test_svdot_single_za32_vg1x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za32_vg1x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_u16,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za32_vg1x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_u16,,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_single_za32_vg1x2_u8j11svuint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_u8,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_single_za32_vg1x4_u8j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_u8,,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za64_vg1x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za64_vg1x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za64_vg1x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za64,,_u16,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za64_vg1x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za64_vg1x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.single.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za64_vg1x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za64,,_u16,,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, single (signed) +// CHECK-LABEL: @test_svdot_single_za32_vg1x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za32_vg1x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_s16,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za32_vg1x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_s16,,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_single_za32_vg1x2_s8j10svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x2_s8(uint32_t slice_base, svint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_s8,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za32_vg1x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svdot_single_za32_vg1x4_s8j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_vg1x4_s8(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za32,,_s8,,_vg1x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za64_vg1x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za64_vg1x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za64_vg1x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za64,,_s16,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svdot_single_za64_vg1x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svdot_single_za64_vg1x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.single.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za64_vg1x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_single_za64,,_s16,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed (unsigned) +// CHECK-LABEL: @test_svdot_lane_za32_vg1x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za32_vg1x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,_u16,,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za32_vg1x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,_u16,,_vg1x4)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svdot_lane_za32_vg1x2_u8j11svuint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,_u8,,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svdot_lane_za32_vg1x4_u8j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,_u8,,_vg1x4)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za64_vg1x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za64_vg1x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za64_vg1x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za64,,,_u16,_vg1x2)(slice_base, zn, zm, 1); +} + +// CHECK-LABEL: @test_svdot_lane_za64_vg1x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za64_vg1x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.udot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za64_vg1x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za64,,,_u16,_vg1x4)(slice_base, zn, zm, 1); +} + + +// +// Multi, indexed (signed) +// CHECK-LABEL: @test_svdot_lane_za32_vg1x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za32_vg1x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,,_s16,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za32_vg1x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,,_s16,_vg1x4)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svdot_lane_za32_vg1x2_s8j10svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x2_s8(uint32_t slice_base, svint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,,_s8,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za32_vg1x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svdot_lane_za32_vg1x4_s8j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_vg1x4_s8(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za32,,,_s8,_vg1x4)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svdot_lane_za64_vg1x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za64_vg1x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za64.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za64_vg1x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za64,,,_s16,_vg1x2)(slice_base, zn, zm, 1); +} + +// CHECK-LABEL: @test_svdot_lane_za64_vg1x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svdot_lane_za64_vg1x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sdot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za64_vg1x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svdot_lane_za64,,,_s16,_vg1x4)(slice_base, zn, zm, 1); +} + + +// +// Multi, multi (unsigned by signed) +// CHECK-LABEL: @test_svusdot_multi_za32_vg1x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svusdot_multi_za32_vg1x2_u8j11svuint8x2_t10svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svusdot_multi_za32_vg1x2_u8(uint32_t slice_base, svuint8x2_t zn, svint8x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusdot_za32,,,_u8,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svusdot_multi_za32_vg1x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svusdot_multi_za32_vg1x4_u8j11svuint8x4_t10svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svusdot_multi_za32_vg1x4_u8(uint32_t slice_base, svuint8x4_t zn, svint8x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusdot_za32,,,_u8,_vg1x4)(slice_base, zn, zm); +} + + +// +// Multi, single (unsigned by signed) +// CHECK-LABEL: @test_svusdot_single_za32_vg1x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z33test_svusdot_single_za32_vg1x2_u8j11svuint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svusdot_single_za32_vg1x2_u8(uint32_t slice_base, svuint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusdot_single_za32,,_u8,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svusdot_single_za32_vg1x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z33test_svusdot_single_za32_vg1x4_u8j11svuint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svusdot_single_za32_vg1x4_u8(uint32_t slice_base, svuint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusdot_single_za32,,_u8,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed (unsigned by signed) +// CHECK-LABEL: @test_svusdot_lane_za32_vg1x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svusdot_lane_za32_vg1x2_u8j11svuint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svusdot_lane_za32_vg1x2_u8(uint32_t slice_base, svuint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusdot_lane_za32,,_u8,,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svusdot_lane_za32_vg1x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svusdot_lane_za32_vg1x4_u8j11svuint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svusdot_lane_za32_vg1x4_u8(uint32_t slice_base, svuint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusdot_lane_za32,,_u8,,_vg1x4)(slice_base, zn, zm, 3); +} + + +// +// Multi, single (signed by unsigned) +// CHECK-LABEL: @test_svsudot_single_za32_vg1x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z33test_svsudot_single_za32_vg1x2_s8j10svint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.single.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svsudot_single_za32_vg1x2_s8(uint32_t slice_base, svint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsudot_single_za32,,_s8,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svsudot_single_za32_vg1x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z33test_svsudot_single_za32_vg1x4_s8j10svint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.single.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svsudot_single_za32_vg1x4_s8(uint32_t slice_base, svint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsudot_single_za32,,_s8,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, multi (signed by unsigned) +// CHECK-LABEL: @test_svsudot_multi_za32_vg1x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP2]], [[TMP3]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svsudot_multi_za32_vg1x2_s8j10svint8x2_t11svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP2]], [[TMP3]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svsudot_multi_za32_vg1x2_s8(uint32_t slice_base, svint8x2_t zn, svuint8x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsudot_za32,,_s8,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svsudot_multi_za32_vg1x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svsudot_multi_za32_vg1x4_s8j10svint8x4_t11svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usdot.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svsudot_multi_za32_vg1x4_s8(uint32_t slice_base, svint8x4_t zn, svuint8x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsudot_za32,,_s8,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed (signed by unsigned) +// CHECK-LABEL: @test_svsudot_lane_za32_vg1x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svsudot_lane_za32_vg1x2_s8j10svint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.lane.za32.vg1x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svsudot_lane_za32_vg1x2_s8(uint32_t slice_base, svint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsudot_lane_za32,,_s8,,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svsudot_lane_za32_vg1x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svsudot_lane_za32_vg1x4_s8j10svint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sudot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svsudot_lane_za32_vg1x4_s8(uint32_t slice_base, svint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsudot_lane_za32,,_s8,,_vg1x4)(slice_base, zn, zm, 3); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mla.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mla.c new file mode 100644 index 0000000000000000000000000000000000000000..f52edd9888daa93275f5893dc02f15450cc769bf --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mla.c @@ -0,0 +1,292 @@ +// 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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Multi, multi +// CHECK-LABEL: @test_svmla2_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla2_f32j13svfloat32x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla2_f32(uint32_t slice_base, svfloat32x2_t zn, svfloat32x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_za32,_f32,_vg1x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla4_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla4_f32j13svfloat32x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla4_f32(uint32_t slice_base, svfloat32x4_t zn, svfloat32x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_za32,_f32,_vg1x4,,)(slice_base, zn, zm); +} + +// +// Multi, single +// CHECK-LABEL: @test_svmla_single2_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single2_f32j13svfloat32x2_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single2_f32(uint32_t slice_base, svfloat32x2_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_single_za32,,_f32,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single4_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single4_f32j13svfloat32x4_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single4_f32(uint32_t slice_base, svfloat32x4_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_single_za32,,_f32,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed +// CHECK-LABEL: @test_svmla_lane2_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane2_f32j13svfloat32x2_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane2_f32(uint32_t slice_base, svfloat32x2_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_lane_za32,_f32,_vg1x2,,)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svmla_lane4_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane4_f32j13svfloat32x4_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane4_f32(uint32_t slice_base, svfloat32x4_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_lane_za32,_f32,_vg1x4,,)(slice_base, zn, zm, 3); +} + +// +// Multi, multi +// CHECK-LABEL: @test_svmla2_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla2_f64j13svfloat64x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla2_f64(uint32_t slice_base, svfloat64x2_t zn, svfloat64x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_za64,_f64,_vg1x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla4_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla4_f64j13svfloat64x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmla.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla4_f64(uint32_t slice_base, svfloat64x4_t zn, svfloat64x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_za64,_f64,_vg1x4,,)(slice_base, zn, zm); +} + +// +// Multi, single +// CHECK-LABEL: @test_svmla_single2_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single2_f64j13svfloat64x2_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single2_f64(uint32_t slice_base, svfloat64x2_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_single_za64,,_f64,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single4_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single4_f64j13svfloat64x4_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.single.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single4_f64(uint32_t slice_base, svfloat64x4_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_single_za64,,_f64,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed +// CHECK-LABEL: @test_svmla_lane2_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane2_f64j13svfloat64x2_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane2_f64(uint32_t slice_base, svfloat64x2_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_lane_za64,_f64,_vg1x2,,)(slice_base, zn, zm, 1); +} + +// CHECK-LABEL: @test_svmla_lane4_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane4_f64j13svfloat64x4_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmla.lane.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane4_f64(uint32_t slice_base, svfloat64x4_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmla_lane_za64,_f64,_vg1x4,,)(slice_base, zn, zm, 1); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlal.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlal.c new file mode 100644 index 0000000000000000000000000000000000000000..834ade753507675b0ad28dd5cff0befe6614e4a2 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlal.c @@ -0,0 +1,696 @@ +// 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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Multi, multi +// CHECK-LABEL: @test_svmla2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlal.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla2_f16j13svfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlal.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_f16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z16test_svmla2_bf16j14svbfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_bf16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla2_u16j12svuint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_u16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla2_s16j11svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla2_s16(uint32_t slice_base, svint16x2_t zn, svint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_s16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlal.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla4_f16j13svfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlal.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_f16,_vg2x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z16test_svmla4_bf16j14svbfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_bf16,_vg2x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla4_u16j12svuint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_u16,_vg2x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmla4_s16j11svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla4_s16(uint32_t slice_base, svint16x4_t zn, svint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_s16,_vg2x4,,)(slice_base, zn, zm); +} + +// +// Multi, single +// CHECK-LABEL: @test_svmla_single1_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single1_f16ju13__SVFloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single1_f16(uint32_t slice_base, svfloat16_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_f16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single1_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single1_bf16ju14__SVBfloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single1_bf16(uint32_t slice_base, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_bf16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_u16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_s16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single2_f16j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_f16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single2_bf16j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_bf16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_u16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_s16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single4_f16j13svfloat16x4_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_f16,,_vg2x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single4_bf16j14svbfloat16x4_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.single.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_bf16,,_vg2x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_u16,,_vg2x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmla_single4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_s16,,_vg2x4)(slice_base, zn, zm); +} + +// +// Multi, indexed +// + +// CHECK-LABEL: @test_svmla_lane1_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane1_f16ju13__SVFloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane1_f16(uint32_t slice_base, svfloat16_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_f16,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane1_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_svmla_lane1_bf16ju14__SVBfloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane1_bf16(uint32_t slice_base, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_bf16,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_u16,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_s16,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane2_f16j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_f16,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_svmla_lane2_bf16j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_bf16,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_u16,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_s16,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane4_f16j13svfloat16x4_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_f16,_vg2x4)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_svmla_lane4_bf16j14svbfloat16x4_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlal.lane.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_bf16,_vg2x4)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlal.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_u16,_vg2x4)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmla_lane4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmla_lane4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlal.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,,,_s16,_vg2x4)(slice_base, zn, zm, 7); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlall.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlall.c new file mode 100644 index 0000000000000000000000000000000000000000..fceb16a482600d1f62a7b9f7fb1ae23b0d4869a8 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlall.c @@ -0,0 +1,1790 @@ +// 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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -target-feature +sme-i16i64 -S -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 +sme2 -S -target-feature +sme-i16i64 -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 +sme2 -target-feature +sme-i16i64 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Single x 1 +// + +// MLAL + +// CHECK-LABEL: @test_svmla_single_x1_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single_x1_s8ju10__SVInt8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x1_s8(uint32_t slice_base, svint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_s8,_vg4x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmla_single_x1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za64,_s16,_vg4x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_uvmlal_single_x1_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_uvmlal_single_x1_u8ju11__SVUint8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_uvmlal_single_x1_u8(uint32_t slice_base, svuint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_u8,_vg4x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_uvmlal_single_x1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_uvmlal_single_x1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_uvmlal_single_x1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za64,_u16,_vg4x1,,)(slice_base, zn, zm); +} + +// MLSL + +// CHECK-LABEL: @test_svmls_single_x1_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single_x1_s8ju10__SVInt8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x1_s8(uint32_t slice_base, svint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_s8,_vg4x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmls_single_x1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za64,_s16,_vg4x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_uvmlsl_single_x1_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_uvmlsl_single_x1_u8ju11__SVUint8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_uvmlsl_single_x1_u8(uint32_t slice_base, svuint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_u8,_vg4x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_uvmlsl_single_x1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_uvmlsl_single_x1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.single.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_uvmlsl_single_x1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za64,_u16,_vg4x1,,)(slice_base, zn, zm); +} + +// SUMLALL + +// CHECK-LABEL: @test_sumlall_single_x1_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZM:%.*]], [[ZN:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_sumlall_single_x1_s8ju10__SVInt8_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZM:%.*]], [[ZN:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_sumlall_single_x1_s8(uint32_t slice_base, svint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_za32,_s8,_vg4x1,,)(slice_base, zn, zm); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlall_single_x1_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_usmlall_single_x1_u8ju11__SVUint8_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_usmlall_single_x1_u8(uint32_t slice_base, svuint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_za32,_u8,_vg4x1,,)(slice_base, zn, zm); +} + +// +// Single x 2 +// + +// MLAL + +// CHECK-LABEL: @test_svmla_single_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single_x2_s8j10svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x2_s8(uint32_t slice_base, svint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_s8,,_vg4x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmla_single_x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za64,,_s16,,_vg4x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single_x2_u8j11svuint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_u8,,_vg4x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmla_single_x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za64,,_u16,,_vg4x2)(slice_base, zn, zm); +} + +// MLSL + +// CHECK-LABEL: @test_svmls_single_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single_x2_s8j10svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x2_s8(uint32_t slice_base, svint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_s8,,_vg4x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmls_single_x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za64,,_s16,,_vg4x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single_x2_u8j11svuint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_u8,,_vg4x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmls_single_x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.single.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za64,,_u16,,_vg4x2)(slice_base, zn, zm); +} + +// SUMLALL + +// CHECK-LABEL: @test_svsumla_single_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_svsumla_single_x2_s8j10svint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svsumla_single_x2_s8(uint32_t slice_base, svint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_single_za32,,_s8,,_vg4x2)(slice_base, zn, zm); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlall_single_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_usmlall_single_x2_u8j11svuint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_usmlall_single_x2_u8(uint32_t slice_base, svuint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_single_za32,,_u8,,_vg4x2)(slice_base, zn, zm); +} + +// +// Single x 4 +// + +// MLAL + +// CHECK-LABEL: @test_svmla_single_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single_x4_s8j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x4_s8(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_s8,,_vg4x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmla_single_x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za64,,_s16,,_vg4x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmla_single_x4_u8j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za32,,_u8,,_vg4x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmla_single_x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmla_single_x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_single_x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_single_za64,,_u16,,_vg4x4)(slice_base, zn, zm); +} + +// MLSL + +// CHECK-LABEL: @test_svmls_single_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single_x4_s8j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x4_s8(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_s8,,_vg4x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmls_single_x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za64,,_s16,,_vg4x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single_x4_u8j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_u8,,_vg4x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single_x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z24test_svmls_single_x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.single.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single_x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za64,,_u16,,_vg4x4)(slice_base, zn, zm); +} + +// SUMLALL + +// CHECK-LABEL: @test_svsumla_single_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_svsumla_single_x4_s8j10svint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svsumla_single_x4_s8(uint32_t slice_base, svint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_single_za32,,_s8,,_vg4x4)(slice_base, zn, zm); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlall_single_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_usmlall_single_x4_u8j11svuint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.single.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_usmlall_single_x4_u8(uint32_t slice_base, svuint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_single_za32,,_u8,,_vg4x4)(slice_base, zn, zm); +} + +// +// Multi x 2 +// + +// MLAL + +// CHECK-LABEL: @test_mlal_multi_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlal_multi_x2_s8j10svint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x2_s8(uint32_t slice_base, svint8x2_t zn, svint8x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_s8,_vg4x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlal_multi_x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlal_multi_x2_s16j11svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x2_s16(uint32_t slice_base, svint16x2_t zn, svint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za64,_s16,_vg4x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlal_multi_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlal_multi_x2_u8j11svuint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_u8,_vg4x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlal_multi_x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlal_multi_x2_u16j12svuint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za64,_u16,_vg4x2,,)(slice_base, zn, zm); +} + +// MLSL + +// CHECK-LABEL: @test_mlsl_multi_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlsl_multi_x2_s8j10svint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x2_s8(uint32_t slice_base, svint8x2_t zn, svint8x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_s8,_vg4x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlsl_multi_x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlsl_multi_x2_s16j11svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x2_s16(uint32_t slice_base, svint16x2_t zn, svint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za64,_s16,_vg4x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlsl_multi_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlsl_multi_x2_u8j11svuint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_u8,_vg4x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlsl_multi_x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlsl_multi_x2_u16j12svuint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za64,_u16,_vg4x2,,)(slice_base, zn, zm); +} + +// SUMLALL + +// CHECK-LABEL: @test_sumlal_multi_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP2]], [[TMP3]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_sumlal_multi_x2_s8j10svint8x2_t11svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP2]], [[TMP3]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_sumlal_multi_x2_s8(uint32_t slice_base, svint8x2_t zn, svuint8x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_za32,_s8,_vg4x2,,)(slice_base, zn, zm); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlal_multi_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_usmlal_multi_x2_u8j11svuint8x2_t10svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_usmlal_multi_x2_u8(uint32_t slice_base, svuint8x2_t zn, svint8x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_za32,_u8,_vg4x2,,)(slice_base, zn, zm); +} + +// +// Multi x 4 +// + +// MLAL + +// CHECK-LABEL: @test_mlal_multi_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlal_multi_x4_s8j10svint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x4_s8(uint32_t slice_base, svint8x4_t zn, svint8x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_s8,_vg4x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlal_multi_x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlal_multi_x4_s16j11svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x4_s16(uint32_t slice_base, svint16x4_t zn, svint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za64,_s16,_vg4x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlal_multi_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlal_multi_x4_u8j11svuint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za32,_u8,_vg4x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlal_multi_x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlal_multi_x4_u16j12svuint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlal_multi_x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_za64,_u16,_vg4x4,,)(slice_base, zn, zm); +} + +// MLSL + +// CHECK-LABEL: @test_mlsl_multi_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlsl_multi_x4_s8j10svint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x4_s8(uint32_t slice_base, svint8x4_t zn, svint8x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_s8,_vg4x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlsl_multi_x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlsl_multi_x4_s16j11svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x4_s16(uint32_t slice_base, svint16x4_t zn, svint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za64,_s16,_vg4x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlsl_multi_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_mlsl_multi_x4_u8j11svuint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_u8,_vg4x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_mlsl_multi_x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_mlsl_multi_x4_u16j12svuint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_mlsl_multi_x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za64,_u16,_vg4x4,,)(slice_base, zn, zm); +} + +// SUMLALL + +// CHECK-LABEL: @test_sumlal_multi_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_sumlal_multi_x4_s8j10svint8x4_t11svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_sumlal_multi_x4_s8(uint32_t slice_base, svint8x4_t zn, svuint8x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_za32,_s8,_vg4x4,,)(slice_base, zn, zm); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlal_multi_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_usmlal_multi_x4_u8j11svuint8x4_t10svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_usmlal_multi_x4_u8(uint32_t slice_base, svuint8x4_t zn, svint8x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_za32,_u8,_vg4x4,,)(slice_base, zn, zm); +} + +// +// Indexed x 1 +// + +// SMLAL + +// CHECK-LABEL: @test_smlal_lane_x1_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlal_lane_x1_s8ju10__SVInt8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x1_s8(uint32_t slice_base, svint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,_s8,_vg4x1,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlal_lane_x1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlal_lane_x1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za64,_s16,_vg4x1,,)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_smlal_lane_x1_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlal_lane_x1_u8ju11__SVUint8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x1_u8(uint32_t slice_base, svuint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,_u8,_vg4x1,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlal_lane_x1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlal_lane_x1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za64,_u16,_vg4x1,,)(slice_base, zn, zm, 7); +} + +// SMLSL + +// CHECK-LABEL: @test_smlsl_lane_x1_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlsl_lane_x1_s8ju10__SVInt8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x1_s8(uint32_t slice_base, svint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,_s8,_vg4x1,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlsl_lane_x1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlsl_lane_x1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za64,_s16,_vg4x1,,)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_smlsl_lane_x1_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlsl_lane_x1_u8ju11__SVUint8_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x1_u8(uint32_t slice_base, svuint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,_u8,_vg4x1,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlsl_lane_x1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlsl_lane_x1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.lane.vg4x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za64,_u16,_vg4x1,,)(slice_base, zn, zm, 7); +} + +// SUMLALL + +// CHECK-LABEL: @test_sumlall_lane_x1_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_sumlall_lane_x1_s8ju10__SVInt8_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_sumlall_lane_x1_s8(uint32_t slice_base, svint8_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_lane_za32,_s8,_vg4x1,,)(slice_base, zn, zm, 15); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlall_lane_x1_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_usmlall_lane_x1_u8ju11__SVUint8_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.lane.vg4x1.nxv16i8(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_usmlall_lane_x1_u8(uint32_t slice_base, svuint8_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_lane_za32,_u8,_vg4x1,,)(slice_base, zn, zm, 15); +} + +// +// Indexed x 2 +// + +// SMLAL + +// CHECK-LABEL: @test_smlal_lane_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlal_lane_x2_s8j10svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x2_s8(uint32_t slice_base, svint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,_s8,_vg4x2,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlal_lane_x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlal_lane_x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za64,_s16,_vg4x2,,)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_smlal_lane_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlal_lane_x2_u8j11svuint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,_u8,_vg4x2,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlal_lane_x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlal_lane_x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za64,_u16,_vg4x2,,)(slice_base, zn, zm, 7); +} + +// SMLSL + +// CHECK-LABEL: @test_smlsl_lane_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlsl_lane_x2_s8j10svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x2_s8(uint32_t slice_base, svint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,_s8,_vg4x2,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlsl_lane_x2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlsl_lane_x2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za64,_s16,_vg4x2,,)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_smlsl_lane_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlsl_lane_x2_u8j11svuint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x2_u8(uint32_t slice_base, svuint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,_u8,_vg4x2,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlsl_lane_x2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlsl_lane_x2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.lane.vg4x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za64,_u16,_vg4x2,,)(slice_base, zn, zm, 7); +} + +// SUMLALL + +// CHECK-LABEL: @test_sumlall_lane_x2_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_sumlall_lane_x2_s8j10svint8x2_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_sumlall_lane_x2_s8(uint32_t slice_base, svint8x2_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_lane_za32,_s8,_vg4x2,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_usmlall_lane_x2_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_usmlall_lane_x2_u8j11svuint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.lane.vg4x2.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_usmlall_lane_x2_u8(uint32_t slice_base, svuint8x2_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_lane_za32,_u8,_vg4x2,,)(slice_base, zn, zm, 15); +} + +// +// Indexed x 4 +// + +// MLAL + +// CHECK-LABEL: @test_smlal_lane_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlal_lane_x4_s8j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x4_s8(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,_s8,_vg4x4,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlal_lane_x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlal_lane_x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smla.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za64,_s16,_vg4x4,,)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_smlal_lane_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlal_lane_x4_u8j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za32,_u8,_vg4x4,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlal_lane_x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlal_lane_x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umla.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlal_lane_x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmla_lane_za64,_u16,_vg4x4,,)(slice_base, zn, zm, 7); +} + +// MLSL + +// CHECK-LABEL: @test_smlsl_lane_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlsl_lane_x4_s8j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x4_s8(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,_s8,_vg4x4,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlsl_lane_x4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlsl_lane_x4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smls.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za64,_s16,_vg4x4,,)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_smlsl_lane_x4_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_smlsl_lane_x4_u8j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x4_u8(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,_u8,_vg4x4,,)(slice_base, zn, zm, 15); +} + +// CHECK-LABEL: @test_smlsl_lane_x4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_smlsl_lane_x4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umls.za64.lane.vg4x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_smlsl_lane_x4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za64,_u16,_vg4x4,,)(slice_base, zn, zm, 7); +} + +// SUMLALL + +// CHECK-LABEL: @test_sumlall_lane_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_sumlall_lane_x4_s8j10svint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.sumla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_sumlall_lane_x4_s8(uint32_t slice_base, svint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svsumla_lane_za32,_s8,_vg4x4,,)(slice_base, zn, zm, 15); +} + +// USMLALL + +// CHECK-LABEL: @test_usmlall_lane_x4_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_usmlall_lane_x4_s8j11svuint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usmla.za32.lane.vg4x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_usmlall_lane_x4_s8(uint32_t slice_base, svuint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svusmla_lane_za32,_u8,_vg4x4,,)(slice_base, zn, zm, 15); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mls.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mls.c new file mode 100644 index 0000000000000000000000000000000000000000..6830a399e91d6478b1895a3d9190ff4b9969e315 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mls.c @@ -0,0 +1,292 @@ +// 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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-f64f64 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Multi, multi +// CHECK-LABEL: @test_svmls2_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls2_f32j13svfloat32x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls2_f32(uint32_t slice_base, svfloat32x2_t zn, svfloat32x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_za32,,_f32,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls4_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls4_f32j13svfloat32x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls4_f32(uint32_t slice_base, svfloat32x4_t zn, svfloat32x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_za32,,_f32,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, single +// CHECK-LABEL: @test_svmls_single2_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single2_f32j13svfloat32x2_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single2_f32(uint32_t slice_base, svfloat32x2_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_single_za32,,_f32,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single4_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single4_f32j13svfloat32x4_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single4_f32(uint32_t slice_base, svfloat32x4_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_single_za32,,_f32,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed +// CHECK-LABEL: @test_svmls_lane2_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane2_f32j13svfloat32x2_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x2.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane2_f32(uint32_t slice_base, svfloat32x2_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_lane_za32,,_f32,,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svmls_lane4_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane4_f32j13svfloat32x4_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x4.nxv4f32(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane4_f32(uint32_t slice_base, svfloat32x4_t zn, svfloat32_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_lane_za32,,_f32,,_vg1x4)(slice_base, zn, zm, 3); +} + +// +// Multi, multi +// CHECK-LABEL: @test_svmls2_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls2_f64j13svfloat64x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls2_f64(uint32_t slice_base, svfloat64x2_t zn, svfloat64x2_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_za64,,_f64,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls4_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls4_f64j13svfloat64x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmls.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls4_f64(uint32_t slice_base, svfloat64x4_t zn, svfloat64x4_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_za64,,_f64,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, single +// CHECK-LABEL: @test_svmls_single2_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single2_f64j13svfloat64x2_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single2_f64(uint32_t slice_base, svfloat64x2_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_single_za64,,_f64,,_vg1x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single4_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single4_f64j13svfloat64x4_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.single.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single4_f64(uint32_t slice_base, svfloat64x4_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_single_za64,,_f64,,_vg1x4)(slice_base, zn, zm); +} + +// +// Multi, indexed +// CHECK-LABEL: @test_svmls_lane2_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane2_f64j13svfloat64x2_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x2.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane2_f64(uint32_t slice_base, svfloat64x2_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_lane_za64,,_f64,,_vg1x2)(slice_base, zn, zm, 1); +} + +// CHECK-LABEL: @test_svmls_lane4_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane4_f64j13svfloat64x4_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmls.lane.vg1x4.nxv2f64(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane4_f64(uint32_t slice_base, svfloat64x4_t zn, svfloat64_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svmls_lane_za64,,_f64,,_vg1x4)(slice_base, zn, zm, 1); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlsl.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlsl.c new file mode 100644 index 0000000000000000000000000000000000000000..0a87d97f649c90ea0a74be0197eadadbc8c7b3f0 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mlsl.c @@ -0,0 +1,696 @@ +// 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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// +// Multi, multi +// CHECK-LABEL: @test_svmls2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlsl.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls2_f16j13svfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlsl.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_f16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z16test_svmls2_bf16j14svbfloat16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_bf16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls2_u16j12svuint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_u16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls2_s16j11svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls2_s16(uint32_t slice_base, svint16x2_t zn, svint16x2_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_s16,_vg2x2,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlsl.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls4_f16j13svfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], 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: tail call void @llvm.aarch64.sme.fmlsl.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_f16,_vg2x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z16test_svmls4_bf16j14svbfloat16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_bf16,_vg2x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls4_u16j12svuint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_u16,_vg2x4,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z15test_svmls4_s16j11svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls4_s16(uint32_t slice_base, svint16x4_t zn, svint16x4_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_s16,_vg2x4,,)(slice_base, zn, zm); +} + +// +// Multi, single +// CHECK-LABEL: @test_svmls_single1_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single1_f16ju13__SVFloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single1_f16(uint32_t slice_base, svfloat16_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_f16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single1_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single1_bf16ju14__SVBfloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single1_bf16(uint32_t slice_base, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_bf16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_u16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.single.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_za32,_s16,_vg2x1,,)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single2_f16j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_f16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single2_bf16j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_bf16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_u16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.single.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_s16,,_vg2x2)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single4_f16j13svfloat16x4_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_f16,,_vg2x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z23test_svmls_single4_bf16j14svbfloat16x4_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.single.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_bf16,,_vg2x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_u16,,_vg2x4)(slice_base, zn, zm); +} + +// CHECK-LABEL: @test_svmls_single4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z22test_svmls_single4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.single.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_single4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_single_za32,,_s16,,_vg2x4)(slice_base, zn, zm); +} + +// +// Multi, indexed +// + +// CHECK-LABEL: @test_svmls_lane1_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane1_f16ju13__SVFloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x1.nxv8f16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane1_f16(uint32_t slice_base, svfloat16_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_f16,,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane1_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_svmls_lane1_bf16ju14__SVBfloat16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x1.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane1_bf16(uint32_t slice_base, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_bf16,,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane1_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane1_u16ju12__SVUint16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane1_u16(uint32_t slice_base, svuint16_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_u16,,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane1_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane1_s16ju11__SVInt16_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.lane.vg2x1.nxv8i16(i32 [[SLICE_BASE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane1_s16(uint32_t slice_base, svint16_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_s16,,_vg2x1)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane2_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane2_f16j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane2_f16(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_f16,,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane2_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_svmls_lane2_bf16j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane2_bf16(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_bf16,,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane2_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane2_u16j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane2_u16(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_u16,,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane2_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane2_s16j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.lane.vg2x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane2_s16(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_s16,,_vg2x2)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane4_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane4_f16j13svfloat16x4_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x4.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane4_f16(uint32_t slice_base, svfloat16x4_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_f16,,_vg2x4)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane4_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z21test_svmls_lane4_bf16j14svbfloat16x4_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fmlsl.lane.vg2x4.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane4_bf16(uint32_t slice_base, svbfloat16x4_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_bf16,,_vg2x4)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane4_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane4_u16j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.umlsl.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane4_u16(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_u16,,_vg2x4)(slice_base, zn, zm, 7); +} + +// CHECK-LABEL: @test_svmls_lane4_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z20test_svmls_lane4_s16j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.smlsl.lane.vg2x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmls_lane4_s16(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za +{ + SVE_ACLE_FUNC(svmls_lane_za32,,_s16,,_vg2x4)(slice_base, zn, zm, 7); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_read.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_read.c new file mode 100644 index 0000000000000000000000000000000000000000..583a7fc8154728d3d728c4d8fd10752767db5d6a --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_read.c @@ -0,0 +1,1880 @@ +// 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 +sme2 -target-feature +sve -S -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 +sme2 -target-feature +sve -S -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 +sme2 -target-feature +sve -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +#include + +// CHECK-LABEL: @test_svread_ver_za8_u8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_ver_za8_u8_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint8x2_t test_svread_ver_za8_u8_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za8_u8_vg2(0, base); +} + +// CHECK-LABEL: @test_svread_ver_za8_s8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_ver_za8_s8_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint8x2_t test_svread_ver_za8_s8_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za8_s8_vg2(0, base); +} + +// CHECK-LABEL: @test_svread_hor_za8_u8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_hor_za8_u8_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint8x2_t test_svread_hor_za8_u8_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za8_u8_vg2(0, base); +} + +// CHECK-LABEL: @test_svread_hor_za8_s8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_hor_za8_s8_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint8x2_t test_svread_hor_za8_s8_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za8_s8_vg2(0, base); +} + +// CHECK-LABEL: @test_svread_hor_za8_u8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_hor_za8_u8_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint8x4_t test_svread_hor_za8_u8_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za8_u8_vg4(0, base); +} + +// CHECK-LABEL: @test_svread_hor_za8_s8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_hor_za8_s8_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint8x4_t test_svread_hor_za8_s8_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za8_s8_vg4(0, base); +} + +// CHECK-LABEL: @test_svread_ver_za8_u8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_ver_za8_u8_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint8x4_t test_svread_ver_za8_u8_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za8_u8_vg4(0, base); +} + +// CHECK-LABEL: @test_svread_ver_za8_s8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_ver_za8_s8_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint8x4_t test_svread_ver_za8_s8_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za8_s8_vg4(0, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_u16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za16_u16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint16x2_t test_svread_hor_za16_u16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_u16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_bf16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z29test_svread_hor_za16_bf16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svbfloat16x2_t test_svread_hor_za16_bf16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_bf16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_f16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za16_f16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat16x2_t test_svread_hor_za16_f16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_f16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_s16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za16_s16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint16x2_t test_svread_hor_za16_s16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_s16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_u16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za16_u16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint16x2_t test_svread_ver_za16_u16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_u16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_bf16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z29test_svread_ver_za16_bf16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svbfloat16x2_t test_svread_ver_za16_bf16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_bf16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_f16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za16_f16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat16x2_t test_svread_ver_za16_f16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_f16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_s16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za16_s16_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint16x2_t test_svread_ver_za16_s16_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_s16_vg2(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_u16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za16_u16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint16x4_t test_svread_hor_za16_u16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_u16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_bf16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z29test_svread_hor_za16_bf16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svbfloat16x4_t test_svread_hor_za16_bf16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_bf16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_f16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za16_f16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat16x4_t test_svread_hor_za16_f16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_f16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za16_s16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za16_s16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint16x4_t test_svread_hor_za16_s16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za16_s16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_u16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za16_u16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint16x4_t test_svread_ver_za16_u16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_u16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_bf16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z29test_svread_ver_za16_bf16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svbfloat16x4_t test_svread_ver_za16_bf16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_bf16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_f16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za16_f16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat16x4_t test_svread_ver_za16_f16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_f16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_ver_za16_s16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za16_s16_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint16x4_t test_svread_ver_za16_s16_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za16_s16_vg4(1, base); +} + +// CHECK-LABEL: @test_svread_hor_za32_u32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za32_u32_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint32x2_t test_svread_hor_za32_u32_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za32_u32_vg2(3, base); +} + +// CHECK-LABEL: @test_svread_hor_za32_f32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za32_f32_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat32x2_t test_svread_hor_za32_f32_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za32_f32_vg2(3, base); +} + +// CHECK-LABEL: @test_svread_hor_za32_s32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za32_s32_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint32x2_t test_svread_hor_za32_s32_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za32_s32_vg2(3, base); +} + +// CHECK-LABEL: @test_svread_ver_za32_u32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za32_u32_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint32x2_t test_svread_ver_za32_u32_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za32_u32_vg2(3, base); +} + +// CHECK-LABEL: @test_svread_ver_za32_f32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za32_f32_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat32x2_t test_svread_ver_za32_f32_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za32_f32_vg2(3, base); +} + +// CHECK-LABEL: @test_svread_ver_za32_s32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za32_s32_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint32x2_t test_svread_ver_za32_s32_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za32_s32_vg2(3, base); +} + +// CHECK-LABEL: @test_svread_hor_za32_u32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za32_u32_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint32x4_t test_svread_hor_za32_u32_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za32_u32_vg4(3, base); +} + +// CHECK-LABEL: @test_svread_hor_za32_f32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za32_f32_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat32x4_t test_svread_hor_za32_f32_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za32_f32_vg4(3, base); +} + +// CHECK-LABEL: @test_svread_hor_za32_s32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za32_s32_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint32x4_t test_svread_hor_za32_s32_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za32_s32_vg4(3, base); +} + +// CHECK-LABEL: @test_svread_ver_za32_u32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za32_u32_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint32x4_t test_svread_ver_za32_u32_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za32_u32_vg4(3, base); +} + +// CHECK-LABEL: @test_svread_ver_za32_f32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za32_f32_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat32x4_t test_svread_ver_za32_f32_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za32_f32_vg4(3, base); +} + +// CHECK-LABEL: @test_svread_ver_za32_s32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za32_s32_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint32x4_t test_svread_ver_za32_s32_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za32_s32_vg4(3, base); +} + +// CHECK-LABEL: @test_svread_hor_za64_u64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za64_u64_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint64x2_t test_svread_hor_za64_u64_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za64_u64_vg2(7, base); +} + +// CHECK-LABEL: @test_svread_hor_za64_f64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za64_f64_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat64x2_t test_svread_hor_za64_f64_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za64_f64_vg2(7, base); +} + +// CHECK-LABEL: @test_svread_hor_za64_s64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za64_s64_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint64x2_t test_svread_hor_za64_s64_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za64_s64_vg2(7, base); +} + +// CHECK-LABEL: @test_svread_ver_za64_u64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za64_u64_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint64x2_t test_svread_ver_za64_u64_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za64_u64_vg2(7, base); +} + +// CHECK-LABEL: @test_svread_ver_za64_f64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za64_f64_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat64x2_t test_svread_ver_za64_f64_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za64_f64_vg2(7, base); +} + +// CHECK-LABEL: @test_svread_ver_za64_s64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za64_s64_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint64x2_t test_svread_ver_za64_s64_vg2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za64_s64_vg2(7, base); +} + +// CHECK-LABEL: @test_svread_hor_za64_u64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za64_u64_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint64x4_t test_svread_hor_za64_u64_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za64_u64_vg4(7, base); +} + +// CHECK-LABEL: @test_svread_hor_za64_f64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za64_f64_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat64x4_t test_svread_hor_za64_f64_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za64_f64_vg4(7, base); +} + +// CHECK-LABEL: @test_svread_hor_za64_s64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_hor_za64_s64_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint64x4_t test_svread_hor_za64_s64_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_hor_za64_s64_vg4(7, base); +} + +// CHECK-LABEL: @test_svread_ver_za64_u64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za64_u64_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint64x4_t test_svread_ver_za64_u64_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za64_u64_vg4(7, base); +} + +// CHECK-LABEL: @test_svread_ver_za64_f64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za64_f64_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat64x4_t test_svread_ver_za64_f64_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za64_f64_vg4(7, base); +} + +// CHECK-LABEL: @test_svread_ver_za64_s64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z28test_svread_ver_za64_s64_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint64x4_t test_svread_ver_za64_s64_vg4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_ver_za64_s64_vg4(7, base); +} + +// CHECK-LABEL: @test_svread_za8_s8_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv16i8(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z24test_svread_za8_s8_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv16i8(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint8x2_t test_svread_za8_s8_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za8_s8_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za8_u8_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv16i8(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z24test_svread_za8_u8_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv16i8(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint8x2_t test_svread_za8_u8_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za8_u8_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za16_s16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8i16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za16_s16_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8i16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint16x2_t test_svread_za16_s16_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_s16_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za16_u16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8i16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za16_u16_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8i16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint16x2_t test_svread_za16_u16_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_u16_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za16_bf16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8bf16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z27test_svread_za16_bf16_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8bf16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svbfloat16x2_t test_svread_za16_bf16_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_bf16_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za16_f16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8f16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za16_f16_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8f16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat16x2_t test_svread_za16_f16_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_f16_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za32_s32_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv4i32(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za32_s32_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv4i32(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint32x2_t test_svread_za32_s32_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za32_s32_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za32_u32_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv4i32(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za32_u32_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv4i32(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint32x2_t test_svread_za32_u32_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za32_u32_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za32_f32_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv4f32(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za32_f32_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv4f32(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat32x2_t test_svread_za32_f32_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za32_f32_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za64_u64_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv2i64(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za64_u64_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv2i64(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svuint64x2_t test_svread_za64_u64_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za64_u64_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za64_f64_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv2f64(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za64_f64_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv2f64(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svfloat64x2_t test_svread_za64_f64_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za64_f64_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za64_s64_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv2i64(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za64_s64_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv2i64(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svint64x2_t test_svread_za64_s64_vg1x2(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za64_s64_vg1x2(base); +} + +// CHECK-LABEL: @test_svread_za8_s8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv16i8(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z24test_svread_za8_s8_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv16i8(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint8x4_t test_svread_za8_s8_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za8_s8_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za8_u8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv16i8(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z24test_svread_za8_u8_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv16i8(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP4]], [[TMP5]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint8x4_t test_svread_za8_u8_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za8_u8_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za16_s16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8i16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za16_s16_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8i16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint16x4_t test_svread_za16_s16_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_s16_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za16_u16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8i16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za16_u16_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8i16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint16x4_t test_svread_za16_u16_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_u16_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za16_bf16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8bf16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z27test_svread_za16_bf16_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8bf16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svbfloat16x4_t test_svread_za16_bf16_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_bf16_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za16_f16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8f16(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za16_f16_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8f16(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat16x4_t test_svread_za16_f16_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za16_f16_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za32_s32_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv4i32(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za32_s32_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv4i32(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint32x4_t test_svread_za32_s32_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za32_s32_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za32_u32_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv4i32(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za32_u32_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv4i32(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint32x4_t test_svread_za32_u32_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za32_u32_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za32_f32_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv4f32(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za32_f32_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv4f32(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat32x4_t test_svread_za32_f32_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za32_f32_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za64_u64_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv2i64(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za64_u64_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv2i64(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svuint64x4_t test_svread_za64_u64_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za64_u64_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za64_f64_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv2f64(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za64_f64_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv2f64(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svfloat64x4_t test_svread_za64_f64_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za64_f64_vg1x4(base); +} + +// CHECK-LABEL: @test_svread_za64_s64_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv2i64(i32 [[BASE:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z26test_svread_za64_s64_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv2i64(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , , , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , , , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP0]], 2 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP0]], 3 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint64x4_t test_svread_za64_s64_vg1x4(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + return svread_za64_s64_vg1x4(base); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_sqdmulh.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_sqdmulh.c new file mode 100644 index 0000000000000000000000000000000000000000..6bbd23ccd32a521b36f5a86cde6a0af61baa1024 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_sqdmulh.c @@ -0,0 +1,584 @@ +// 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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -S -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 +sme2 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// Single, x2 + +// CHECK-LABEL: @test_svqdmulh_single_s8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv16i8( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z26test_svqdmulh_single_s8_x210svint8x2_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv16i8( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint8x2_t test_svqdmulh_single_s8_x2(svint8x2_t zdn, svint8_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s8_x2,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_single_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv8i16( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z27test_svqdmulh_single_s16_x211svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv8i16( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint16x2_t test_svqdmulh_single_s16_x2(svint16x2_t zdn, svint16_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s16_x2,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_single_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv4i32( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z27test_svqdmulh_single_s32_x211svint32x2_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv4i32( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint32x2_t test_svqdmulh_single_s32_x2(svint32x2_t zdn, svint32_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s32_x2,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_single_s64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv2i64( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z27test_svqdmulh_single_s64_x211svint64x2_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.single.vgx2.nxv2i64( [[TMP0]], [[TMP1]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint64x2_t test_svqdmulh_single_s64_x2(svint64x2_t zdn, svint64_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s64_x2,,,)(zdn, zm); +} + +// Single, x4 + +// CHECK-LABEL: @test_svqdmulh_single_s8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z26test_svqdmulh_single_s8_x410svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint8x4_t test_svqdmulh_single_s8_x4(svint8x4_t zdn, svint8_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s8_x4,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_single_s16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z27test_svqdmulh_single_s16_x411svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint16x4_t test_svqdmulh_single_s16_x4(svint16x4_t zdn, svint16_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s16_x4,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_single_s32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z27test_svqdmulh_single_s32_x411svint32x4_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint32x4_t test_svqdmulh_single_s32_x4(svint32x4_t zdn, svint32_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s32_x4,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_single_s64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z27test_svqdmulh_single_s64_x411svint64x4_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.single.vgx4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint64x4_t test_svqdmulh_single_s64_x4(svint64x4_t zdn, svint64_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_single_s64_x4,,,)(zdn, zm); +} + +// Multi, x2 + +// CHECK-LABEL: @test_svqdmulh_s8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z19test_svqdmulh_s8_x210svint8x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint8x2_t test_svqdmulh_s8_x2(svint8x2_t zdn, svint8x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s8_x2,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z20test_svqdmulh_s16_x211svint16x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint16x2_t test_svqdmulh_s16_x2(svint16x2_t zdn, svint16x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s16_x2,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z20test_svqdmulh_s32_x211svint32x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint32x2_t test_svqdmulh_s32_x2(svint32x2_t zdn, svint32x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s32_x2,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_s64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZM]], i64 2) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: ret [[TMP8]] +// +// CPP-CHECK-LABEL: @_Z20test_svqdmulh_s64_x211svint64x2_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZM]], i64 2) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , } @llvm.aarch64.sve.sqdmulh.vgx2.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP8]] +// +svint64x2_t test_svqdmulh_s64_x2(svint64x2_t zdn, svint64x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s64_x2,,,)(zdn, zm); +} + +// Multi, x4 + +// CHECK-LABEL: @test_svqdmulh_s8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 16) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP12]], [[TMP13]], i64 32) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP14]], [[TMP15]], i64 48) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z19test_svqdmulh_s8_x410svint8x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZDN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 32) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZM]], i64 48) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 16) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP12]], [[TMP13]], i64 32) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP14]], [[TMP15]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svint8x4_t test_svqdmulh_s8_x4(svint8x4_t zdn, svint8x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s8_x4,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_s16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 8) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP12]], [[TMP13]], i64 16) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP14]], [[TMP15]], i64 24) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z20test_svqdmulh_s16_x411svint16x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZDN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 16) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZM]], i64 24) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 8) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP12]], [[TMP13]], i64 16) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP14]], [[TMP15]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svint16x4_t test_svqdmulh_s16_x4(svint16x4_t zdn, svint16x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s16_x4,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_s32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM]], i64 8) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM]], i64 12) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 4) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP12]], [[TMP13]], i64 8) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP14]], [[TMP15]], i64 12) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z20test_svqdmulh_s32_x411svint32x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZDN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM]], i64 8) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZM]], i64 12) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 4) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP12]], [[TMP13]], i64 8) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP14]], [[TMP15]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svint32x4_t test_svqdmulh_s32_x4(svint32x4_t zdn, svint32x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s32_x4,,,)(zdn, zm); +} + +// CHECK-LABEL: @test_svqdmulh_s64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM:%.*]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM]], i64 2) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM]], i64 4) +// CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM]], i64 6) +// CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP9]], i64 0) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 2) +// CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP12]], [[TMP13]], i64 4) +// CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP14]], [[TMP15]], i64 6) +// CHECK-NEXT: ret [[TMP16]] +// +// CPP-CHECK-LABEL: @_Z20test_svqdmulh_s64_x411svint64x4_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZDN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM]], i64 2) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM]], i64 4) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZM]], i64 6) +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call { , , , } @llvm.aarch64.sve.sqdmulh.vgx4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[TMP4]], [[TMP5]], [[TMP6]], [[TMP7]]) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP8]], 0 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP9]], i64 0) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP8]], 1 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 2) +// CPP-CHECK-NEXT: [[TMP13:%.*]] = extractvalue { , , , } [[TMP8]], 2 +// CPP-CHECK-NEXT: [[TMP14:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP12]], [[TMP13]], i64 4) +// CPP-CHECK-NEXT: [[TMP15:%.*]] = extractvalue { , , , } [[TMP8]], 3 +// CPP-CHECK-NEXT: [[TMP16:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP14]], [[TMP15]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP16]] +// +svint64x4_t test_svqdmulh_s64_x4(svint64x4_t zdn, svint64x4_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svqdmulh,_s64_x4,,,)(zdn, zm); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vdot.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vdot.c new file mode 100644 index 0000000000000000000000000000000000000000..fb313d4cebd72cf380ca9db651368f7924eaf599 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vdot.c @@ -0,0 +1,222 @@ +// 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 +sme2 -target-feature +sme-i16i64 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-i16i64 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-i16i64 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-i16i64 -target-feature +sme-f64f64 -S -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 +sme2 -target-feature +sme-i16i64 -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,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +// CHECK-LABEL: @test_svvdot_lane_za32_bf16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fvdot.lane.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svvdot_lane_za32_bf16_vg1x2j14svbfloat16x2_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fvdot.lane.za32.vg1x2.nxv8bf16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za32_bf16_vg1x2(uint32_t slice_base, svbfloat16x2_t zn, svbfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za32,_bf16,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svvdot_lane_za32_f16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fvdot.lane.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svvdot_lane_za32_f16_vg1x2j13svfloat16x2_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fvdot.lane.za32.vg1x2.nxv8f16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za32_f16_vg1x2(uint32_t slice_base, svfloat16x2_t zn, svfloat16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za32,_f16,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svvdot_lane_za32_s16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.svdot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svvdot_lane_za32_s16_vg1x2j11svint16x2_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.svdot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za32_s16_vg1x2(uint32_t slice_base, svint16x2_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za32,_s16,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svvdot_lane_za32_u16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.uvdot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svvdot_lane_za32_u16_vg1x2j12svuint16x2_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.uvdot.lane.za32.vg1x2.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za32_u16_vg1x2(uint32_t slice_base, svuint16x2_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za32,_u16,_vg1x2)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svvdot_lane_za32_s8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.svdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svvdot_lane_za32_s8_vg1x4j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.svdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za32_s8_vg1x4(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za32,_s8,_vg1x4)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svvdot_lane_za32_u8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.uvdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svvdot_lane_za32_u8_vg1x4j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.uvdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za32_u8_vg1x4(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za32,_u8,_vg1x4)(slice_base, zn, zm, 3); +} + +// CHECK-LABEL: @test_svvdot_lane_za64_s16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.svdot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svvdot_lane_za64_s16_vg1x4j11svint16x4_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.svdot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za64_s16_vg1x4(uint32_t slice_base, svint16x4_t zn, svint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za64,_s16,_vg1x4)(slice_base, zn, zm, 1); +} + +// CHECK-LABEL: @test_svvdot_lane_za64_u16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.uvdot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z31test_svvdot_lane_za64_u16_vg1x4j12svuint16x4_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.uvdot.lane.za64.vg1x4.nxv8i16(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 1) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za64_u16_vg1x4(uint32_t slice_base, svuint16x4_t zn, svuint16_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svvdot_lane_za64,_u16,_vg1x4)(slice_base, zn, zm, 1); +} + + +// CHECK-LABEL: @test_svsuvdot_lane_za32_s8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.suvdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svsuvdot_lane_za32_s8_vg1x4j10svint8x4_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.suvdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svsuvdot_lane_za32_s8_vg1x4(uint32_t slice_base, svint8x4_t zn, svint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svsuvdot_lane_za32,_s8,_vg1x4)(slice_base, zn, zm, 3); +} + + +// CHECK-LABEL: @test_svusvdot_lane_za32_u8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.usvdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z32test_svusvdot_lane_za32_u8_vg1x4j11svuint8x4_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.usvdot.lane.za32.vg1x4.nxv16i8(i32 [[SLICE_BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], [[ZM:%.*]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svusvdot_lane_za32_u8_vg1x4(uint32_t slice_base, svuint8x4_t zn, svuint8_t zm) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svusvdot_lane_za32,_u8,_vg1x4)(slice_base, zn, zm, 3); +} + diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_uzpx2.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_uzpx2.c new file mode 100644 index 0000000000000000000000000000000000000000..118b73972575ff32321a12428bd3c6fafcfeef71 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_uzpx2.c @@ -0,0 +1,651 @@ +// 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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -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 + +// 8-bit UZPs + +// CHECK-LABEL: @test_svuzp_s8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z16test_svuzp_s8_x210svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint8x2_t test_svuzp_s8_x2(svint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s8_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_u8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z16test_svuzp_u8_x211svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint8x2_t test_svuzp_u8_x2(svuint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u8_x2)(zn); +} + +// 16-bit UZPs + +// CHECK-LABEL: @test_svuzp_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_s16_x211svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint16x2_t test_svuzp_s16_x2(svint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_u16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_u16_x212svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint16x2_t test_svuzp_u16_x2(svuint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_f16_x213svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat16x2_t test_svuzp_f16_x2(svfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_f16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzp_bf16_x214svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svbfloat16x2_t test_svuzp_bf16_x2(svbfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_bf16_x2)(zn); +} + +// 32-bit UZPs + +// CHECK-LABEL: @test_svuzp_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint32x2_t test_svuzp_s32_x2(svint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s32_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_u32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_u32_x212svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint32x2_t test_svuzp_u32_x2(svuint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u32_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svuzp_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_f32_x2)(zn); +} + +// 64-bit UZPs + +// CHECK-LABEL: @test_svuzp_s64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_s64_x211svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint64x2_t test_svuzp_s64_x2(svint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s64_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_u64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_u64_x212svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint64x2_t test_svuzp_u64_x2(svuint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u64_x2)(zn); +} + +// CHECK-LABEL: @test_svuzp_f64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_f64_x213svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat64x2_t test_svuzp_f64_x2(svfloat64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_f64_x2)(zn); +} + +// 128-bit UZPs + +// CHECK-LABEL: @test_svuzpq_s8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzpq_s8_x210svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint8x2_t test_svuzpq_s8_x2(svint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s8_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzpq_u8_x211svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint8x2_t test_svuzpq_u8_x2(svuint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u8_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_s16_x211svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint16x2_t test_svuzpq_s16_x2(svint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_u16_x212svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint16x2_t test_svuzpq_u16_x2(svuint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_f16_x213svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat16x2_t test_svuzpq_f16_x2(svfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_f16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z19test_svuzpq_bf16_x214svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svbfloat16x2_t test_svuzpq_bf16_x2(svbfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_bf16_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint32x2_t test_svuzpq_s32_x2(svint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s32_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_u32_x212svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint32x2_t test_svuzpq_u32_x2(svuint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u32_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svuzpq_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_f32_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_s64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_s64_x211svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint64x2_t test_svuzpq_s64_x2(svint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s64_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_u64_x212svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint64x2_t test_svuzpq_u64_x2(svuint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u64_x2)(zn); +} + +// CHECK-LABEL: @test_svuzpq_f64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_f64_x213svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat64x2_t test_svuzpq_f64_x2(svfloat64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_f64_x2)(zn); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_uzpx4.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_uzpx4.c new file mode 100644 index 0000000000000000000000000000000000000000..9dcd995445c25a34fa43851e54ed20d6b92e44a8 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_uzpx4.c @@ -0,0 +1,939 @@ +// 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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -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 + +// 8-bit UZPs + +// CHECK-LABEL: @test_svuzp_s8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z16test_svuzp_s8_x410svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint8x4_t test_svuzp_s8_x4(svint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s8_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_u8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z16test_svuzp_u8_x411svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint8x4_t test_svuzp_u8_x4(svuint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u8_x4)(zn); +} + +// 16-bit UZPs + +// CHECK-LABEL: @test_svuzp_s16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_s16_x411svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint16x4_t test_svuzp_s16_x4(svint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_u16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_u16_x412svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint16x4_t test_svuzp_u16_x4(svuint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_f16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_f16_x413svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat16x4_t test_svuzp_f16_x4(svfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_f16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_bf16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzp_bf16_x414svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svbfloat16x4_t test_svuzp_bf16_x4(svbfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_bf16_x4)(zn); +} + +// 32-bit UZPs + +// CHECK-LABEL: @test_svuzp_s32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_s32_x411svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint32x4_t test_svuzp_s32_x4(svint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s32_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_u32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_u32_x412svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint32x4_t test_svuzp_u32_x4(svuint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u32_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svuzp_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_f32_x4)(zn); +} + +// 64-bit UZPs + +// CHECK-LABEL: @test_svuzp_s64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_s64_x411svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint64x4_t test_svuzp_s64_x4(svint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_s64_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_u64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_u64_x412svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint64x4_t test_svuzp_u64_x4(svuint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_u64_x4)(zn); +} + +// CHECK-LABEL: @test_svuzp_f64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_f64_x413svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat64x4_t test_svuzp_f64_x4(svfloat64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_f64_x4)(zn); +} + +// 128-bit UZPs + +// CHECK-LABEL: @test_svuzpq_s8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzpq_s8_x410svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint8x4_t test_svuzpq_s8_x4(svint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s8_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzpq_u8_x411svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint8x4_t test_svuzpq_u8_x4(svuint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u8_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_s16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_s16_x411svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint16x4_t test_svuzpq_s16_x4(svint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_u16_x412svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint16x4_t test_svuzpq_u16_x4(svuint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_f16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_f16_x413svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat16x4_t test_svuzpq_f16_x4(svfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_f16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_bf16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z19test_svuzpq_bf16_x414svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svbfloat16x4_t test_svuzpq_bf16_x4(svbfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_bf16_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_s32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_s32_x411svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint32x4_t test_svuzpq_s32_x4(svint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s32_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_u32_x412svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint32x4_t test_svuzpq_u32_x4(svuint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u32_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svuzpq_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_f32_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_s64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_s64_x411svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint64x4_t test_svuzpq_s64_x4(svint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_s64_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_u64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_u64_x412svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint64x4_t test_svuzpq_u64_x4(svuint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_u64_x4)(zn); +} + +// CHECK-LABEL: @test_svuzpq_f64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_f64_x413svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat64x4_t test_svuzpq_f64_x4(svfloat64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_f64_x4)(zn); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_zipx2.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_zipx2.c new file mode 100644 index 0000000000000000000000000000000000000000..17555dc7683f46bc7e60c4028bd4991221e6452c --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_zipx2.c @@ -0,0 +1,651 @@ +// 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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -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 + +// 8-bit ZIPs + +// CHECK-LABEL: @test_svzip_s8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z16test_svzip_s8_x210svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint8x2_t test_svzip_s8_x2(svint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s8_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_u8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z16test_svzip_u8_x211svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint8x2_t test_svzip_u8_x2(svuint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u8_x2)(zn); +} + +// 16-bit ZIPs + +// CHECK-LABEL: @test_svzip_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_s16_x211svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint16x2_t test_svzip_s16_x2(svint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s16_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_u16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_u16_x212svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint16x2_t test_svzip_u16_x2(svuint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u16_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_f16_x213svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat16x2_t test_svzip_f16_x2(svfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_f16_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzip_bf16_x214svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svbfloat16x2_t test_svzip_bf16_x2(svbfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_bf16_x2)(zn); +} + +// 32-bit ZIPs + +// CHECK-LABEL: @test_svzip_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint32x2_t test_svzip_s32_x2(svint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s32_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_u32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_u32_x212svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint32x2_t test_svzip_u32_x2(svuint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u32_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svzip_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_f32_x2)(zn); +} + +// 64-bit ZIPs + +// CHECK-LABEL: @test_svzip_s64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_s64_x211svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint64x2_t test_svzip_s64_x2(svint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s64_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_u64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_u64_x212svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint64x2_t test_svzip_u64_x2(svuint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u64_x2)(zn); +} + +// CHECK-LABEL: @test_svzip_f64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_f64_x213svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat64x2_t test_svzip_f64_x2(svfloat64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_f64_x2)(zn); +} + +// 128-bit ZIPs + +// CHECK-LABEL: @test_svzipq_s8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzipq_s8_x210svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint8x2_t test_svzipq_s8_x2(svint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s8_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_u8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z17test_svzipq_u8_x211svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv16i8( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP4]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint8x2_t test_svzipq_u8_x2(svuint8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u8_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_s16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_s16_x211svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint16x2_t test_svzipq_s16_x2(svint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s16_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_u16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_u16_x212svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8i16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint16x2_t test_svzipq_u16_x2(svuint16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u16_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_f16_x213svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8f16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat16x2_t test_svzipq_f16_x2(svfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_f16_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z19test_svzipq_bf16_x214svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8bf16( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16bf16.nxv8bf16( [[TMP4]], [[TMP5]], i64 8) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svbfloat16x2_t test_svzipq_bf16_x2(svbfloat16x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_bf16_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint32x2_t test_svzipq_s32_x2(svint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s32_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_u32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_u32_x212svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint32x2_t test_svzipq_u32_x2(svuint32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u32_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_f32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_f32_x213svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv4f32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP4]], [[TMP5]], i64 4) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat32x2_t test_svzipq_f32_x2(svfloat32x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_f32_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_s64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_s64_x211svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svint64x2_t test_svzipq_s64_x2(svint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s64_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_u64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_u64_x212svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv2i64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svuint64x2_t test_svzipq_u64_x2(svuint64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u64_x2)(zn); +} + +// CHECK-LABEL: @test_svzipq_f64_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_f64_x213svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv2f64( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP2]], 0 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( poison, [[TMP3]], i64 0) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , } [[TMP2]], 1 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP4]], [[TMP5]], i64 2) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svfloat64x2_t test_svzipq_f64_x2(svfloat64x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_f64_x2)(zn); +} + diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_zipx4.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_zipx4.c new file mode 100644 index 0000000000000000000000000000000000000000..ef88f724011bfbbac7f8bbec22e95beb67fc6b7e --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_zipx4.c @@ -0,0 +1,938 @@ +// 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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -S -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 +sve -target-feature +sme2 -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 + +// 8-bit ZIPs + +// CHECK-LABEL: @test_svzip_s8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z16test_svzip_s8_x410svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint8x4_t test_svzip_s8_x4(svint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s8_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_u8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z16test_svzip_u8_x411svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint8x4_t test_svzip_u8_x4(svuint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u8_x4)(zn); +} + +// 16-bit ZIPs + +// CHECK-LABEL: @test_svzip_s16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_s16_x411svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint16x4_t test_svzip_s16_x4(svint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s16_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_u16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_u16_x412svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint16x4_t test_svzip_u16_x4(svuint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u16_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_f16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_f16_x413svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat16x4_t test_svzip_f16_x4(svfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_f16_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_bf16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzip_bf16_x414svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svbfloat16x4_t test_svzip_bf16_x4(svbfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_bf16_x4)(zn); +} + +// 32-bit ZIPs + +// CHECK-LABEL: @test_svzip_s32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_s32_x411svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint32x4_t test_svzip_s32_x4(svint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s32_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_u32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_u32_x412svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint32x4_t test_svzip_u32_x4(svuint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u32_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svzip_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_f32_x4)(zn); +} + +// 64-bit ZIPs + +// CHECK-LABEL: @test_svzip_s64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_s64_x411svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint64x4_t test_svzip_s64_x4(svint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_s64_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_u64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_u64_x412svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint64x4_t test_svzip_u64_x4(svuint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_u64_x4)(zn); +} + +// CHECK-LABEL: @test_svzip_f64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_f64_x413svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat64x4_t test_svzip_f64_x4(svfloat64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_f64_x4)(zn); +} + +// 128-bit ZIPs + +// CHECK-LABEL: @test_svzipq_s8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzipq_s8_x410svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint8x4_t test_svzipq_s8_x4(svint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s8_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_u8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z17test_svzipq_u8_x411svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[ZN]], i64 48) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 16) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP8]], [[TMP9]], i64 32) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP10]], [[TMP11]], i64 48) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint8x4_t test_svzipq_u8_x4(svuint8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u8_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_s16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_s16_x411svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint16x4_t test_svzipq_s16_x4(svint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s16_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_u16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_u16_x412svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint16x4_t test_svzipq_u16_x4(svuint16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u16_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_f16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_f16_x413svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat16x4_t test_svzipq_f16_x4(svfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_f16_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_bf16_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z19test_svzipq_bf16_x414svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[ZN]], i64 24) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8bf16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP6]], [[TMP7]], i64 8) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP8]], [[TMP9]], i64 16) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv32bf16.nxv8bf16( [[TMP10]], [[TMP11]], i64 24) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svbfloat16x4_t test_svzipq_bf16_x4(svbfloat16x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_bf16_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_s32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_s32_x411svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint32x4_t test_svzipq_s32_x4(svint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s32_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_u32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_u32_x412svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint32x4_t test_svzipq_u32_x4(svuint32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u32_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_f32_x413svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[ZN]], i64 12) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 4) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP8]], [[TMP9]], i64 8) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP10]], [[TMP11]], i64 12) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat32x4_t test_svzipq_f32_x4(svfloat32x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_f32_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_s64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_s64_x411svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svint64x4_t test_svzipq_s64_x4(svint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_s64_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_u64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_u64_x412svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svuint64x4_t test_svzipq_u64_x4(svuint64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_u64_x4)(zn); +} + +// CHECK-LABEL: @test_svzipq_f64_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CHECK-NEXT: ret [[TMP12]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_f64_x413svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[ZN]], i64 6) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: [[TMP5:%.*]] = extractvalue { , , , } [[TMP4]], 0 +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( poison, [[TMP5]], i64 0) +// CPP-CHECK-NEXT: [[TMP7:%.*]] = extractvalue { , , , } [[TMP4]], 1 +// CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 2) +// CPP-CHECK-NEXT: [[TMP9:%.*]] = extractvalue { , , , } [[TMP4]], 2 +// CPP-CHECK-NEXT: [[TMP10:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP8]], [[TMP9]], i64 4) +// CPP-CHECK-NEXT: [[TMP11:%.*]] = extractvalue { , , , } [[TMP4]], 3 +// CPP-CHECK-NEXT: [[TMP12:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP10]], [[TMP11]], i64 6) +// CPP-CHECK-NEXT: ret [[TMP12]] +// +svfloat64x4_t test_svzipq_f64_x4(svfloat64x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_f64_x4)(zn); +} diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_write.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_write.c new file mode 100644 index 0000000000000000000000000000000000000000..14b0371bce5742a8f98541812d408489da1ea638 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_write.c @@ -0,0 +1,1457 @@ +// 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 +sme2 -target-feature +sve -S -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 +sme2 -target-feature +sve -S -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 +sme2 -target-feature +sve -S -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 +sme2 -S -target-feature +sve -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 +sme2 -S -target-feature +sve -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,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +// CHECK-LABEL: @test_svwrite_ver_za8_u8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_ver_za8_u8_vg2j11svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za8_u8_vg2(uint32_t base, svuint8x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za8,_u8,_vg2,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za8_s8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_ver_za8_s8_vg2j10svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za8_s8_vg2(uint32_t base, svint8x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za8,_s8,_vg2,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za8_u8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_hor_za8_u8_vg2j11svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za8_u8_vg2(uint32_t base, svuint8x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za8,_u8,_vg2,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za8_s8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_hor_za8_s8_vg2j10svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za8_s8_vg2(uint32_t base, svint8x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za8,_s8,_vg2,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za8_u8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_hor_za8_u8_vg4j11svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za8_u8_vg4(uint32_t base, svuint8x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za8,_u8,_vg4,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za8_s8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_hor_za8_s8_vg4j10svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za8_s8_vg4(uint32_t base, svint8x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za8,_s8,_vg4,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za8_u8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_ver_za8_u8_vg4j11svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za8_u8_vg4(uint32_t base, svuint8x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za8,_u8,_vg4,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za8_s8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_ver_za8_s8_vg4j10svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za8_s8_vg4(uint32_t base, svint8x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za8,_s8,_vg4,)(0, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_u16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za16_u16_vg2j12svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_u16_vg2(uint32_t base, svuint16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_u16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_bf16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svwrite_hor_za16_bf16_vg2j14svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_bf16_vg2(uint32_t base, svbfloat16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_bf16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_f16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za16_f16_vg2j13svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_f16_vg2(uint32_t base, svfloat16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_f16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_s16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za16_s16_vg2j11svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_s16_vg2(uint32_t base, svint16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_s16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_u16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za16_u16_vg2j12svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_u16_vg2(uint32_t base, svuint16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_u16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_bf16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svwrite_ver_za16_bf16_vg2j14svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_bf16_vg2(uint32_t base, svbfloat16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_bf16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_f16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za16_f16_vg2j13svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_f16_vg2(uint32_t base, svfloat16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_f16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_s16_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za16_s16_vg2j11svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_s16_vg2(uint32_t base, svint16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_s16,_vg2,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_u16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za16_u16_vg4j12svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_u16_vg4(uint32_t base, svuint16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_u16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_bf16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svwrite_hor_za16_bf16_vg4j14svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_bf16_vg4(uint32_t base, svbfloat16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_bf16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_f16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za16_f16_vg4j13svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_f16_vg4(uint32_t base, svfloat16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_f16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za16_s16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za16_s16_vg4j11svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za16_s16_vg4(uint32_t base, svint16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za16,_s16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_u16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za16_u16_vg4j12svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_u16_vg4(uint32_t base, svuint16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_u16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_bf16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z30test_svwrite_ver_za16_bf16_vg4j14svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8bf16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_bf16_vg4(uint32_t base, svbfloat16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_bf16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_f16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za16_f16_vg4j13svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8f16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_f16_vg4(uint32_t base, svfloat16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_f16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za16_s16_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za16_s16_vg4j11svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv8i16(i32 1, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za16_s16_vg4(uint32_t base, svint16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za16,_s16,_vg4,)(1, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za32_u32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za32_u32_vg2j12svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za32_u32_vg2(uint32_t base, svuint32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za32,_u32,_vg2,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za32_f32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za32_f32_vg2j13svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za32_f32_vg2(uint32_t base, svfloat32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za32,_f32,_vg2,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za32_s32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za32_s32_vg2j11svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za32_s32_vg2(uint32_t base, svint32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za32,_s32,_vg2,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za32_u32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za32_u32_vg2j12svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za32_u32_vg2(uint32_t base, svuint32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za32,_u32,_vg2,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za32_f32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za32_f32_vg2j13svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za32_f32_vg2(uint32_t base, svfloat32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za32,_f32,_vg2,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za32_s32_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za32_s32_vg2j11svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za32_s32_vg2(uint32_t base, svint32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za32,_s32,_vg2,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za32_u32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za32_u32_vg4j12svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za32_u32_vg4(uint32_t base, svuint32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za32,_u32,_vg4,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za32_f32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za32_f32_vg4j13svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za32_f32_vg4(uint32_t base, svfloat32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za32,_f32,_vg4,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za32_s32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za32_s32_vg4j11svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za32_s32_vg4(uint32_t base, svint32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za32,_s32,_vg4,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za32_u32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za32_u32_vg4j12svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za32_u32_vg4(uint32_t base, svuint32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za32,_u32,_vg4,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za32_f32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za32_f32_vg4j13svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv4f32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za32_f32_vg4(uint32_t base, svfloat32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za32,_f32,_vg4,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za32_s32_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za32_s32_vg4j11svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv4i32(i32 3, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za32_s32_vg4(uint32_t base, svint32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za32,_s32,_vg4,)(3, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za64_u64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za64_u64_vg2j12svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za64_u64_vg2(uint32_t base, svuint64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za64,_u64,_vg2,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za64_f64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za64_f64_vg2j13svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za64_f64_vg2(uint32_t base, svfloat64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za64,_f64,_vg2,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za64_s64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za64_s64_vg2j11svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za64_s64_vg2(uint32_t base, svint64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za64,_s64,_vg2,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za64_u64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za64_u64_vg2j12svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za64_u64_vg2(uint32_t base, svuint64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za64,_u64,_vg2,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za64_f64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za64_f64_vg2j13svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za64_f64_vg2(uint32_t base, svfloat64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za64,_f64,_vg2,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za64_s64_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za64_s64_vg2j11svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za64_s64_vg2(uint32_t base, svint64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za64,_s64,_vg2,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za64_u64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za64_u64_vg4j12svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za64_u64_vg4(uint32_t base, svuint64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za64,_u64,_vg4,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za64_u64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za64_u64_vg4j12svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za64_u64_vg4(uint32_t base, svuint64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za64,_u64,_vg4,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za64_f64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za64_f64_vg4j13svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za64_f64_vg4(uint32_t base, svfloat64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za64,_f64,_vg4,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_hor_za64_s64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_hor_za64_s64_vg4j11svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za64_s64_vg4(uint32_t base, svint64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_hor_za64,_s64,_vg4,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za64_f64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za64_f64_vg4j13svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv2f64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za64_f64_vg4(uint32_t base, svfloat64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za64,_f64,_vg4,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_ver_za64_s64_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z29test_svwrite_ver_za64_s64_vg4j11svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv2i64(i32 7, i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za64_s64_vg4(uint32_t base, svint64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_ver_za64,_s64,_vg4,)(7, base, val); +} + +// CHECK-LABEL: @test_svwrite_za8_s8_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_svwrite_za8_s8_vg1x2j10svint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za8_s8_vg1x2(uint32_t base, svint8x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za8,_s8,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za8_u8_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_svwrite_za8_u8_vg1x2j11svuint8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za8_u8_vg1x2(uint32_t base, svuint8x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za8,_u8,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_s16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za16_s16_vg1x2j11svint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_s16_vg1x2(uint32_t base, svint16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_s16,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_u16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za16_u16_vg1x2j12svuint16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv16i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_u16_vg1x2(uint32_t base, svuint16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_u16,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_bf16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8bf16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z28test_svwrite_za16_bf16_vg1x2j14svbfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv16bf16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8bf16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_bf16_vg1x2(uint32_t base, svbfloat16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_bf16,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_f16_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL]], i64 8) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8f16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za16_f16_vg1x2j13svfloat16x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv16f16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8f16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_f16_vg1x2(uint32_t base, svfloat16x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_f16,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za32_s32_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za32_s32_vg1x2j11svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za32_s32_vg1x2(uint32_t base, svint32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za32,_s32,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za32_u32_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za32_u32_vg1x2j12svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za32_u32_vg1x2(uint32_t base, svuint32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za32,_u32,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za32_f32_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL]], i64 4) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv4f32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za32_f32_vg1x2j13svfloat32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv8f32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv4f32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za32_f32_vg1x2(uint32_t base, svfloat32x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za32,_f32,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za64_u64_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za64_u64_vg1x2j12svuint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za64_u64_vg1x2(uint32_t base, svuint64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za64,_u64,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za64_f64_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv2f64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za64_f64_vg1x2j13svfloat64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv4f64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv2f64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za64_f64_vg1x2(uint32_t base, svfloat64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za64,_f64,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za64_s64_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za64_s64_vg1x2j11svint64x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv4i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za64_s64_vg1x2(uint32_t base, svint64x2_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za64,_s64,_vg1x2,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za8_s8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_svwrite_za8_s8_vg1x4j10svint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za8_s8_vg1x4(uint32_t base, svint8x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za8,_s8,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za8_u8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z25test_svwrite_za8_u8_vg1x4j11svuint8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 32) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv64i8( [[VAL]], i64 48) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za8_u8_vg1x4(uint32_t base, svuint8x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za8,_u8,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_s16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za16_s16_vg1x4j11svint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_s16_vg1x4(uint32_t base, svint16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_s16,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_u16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za16_u16_vg1x4j12svuint16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8i16.nxv32i16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8i16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_u16_vg1x4(uint32_t base, svuint16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_u16,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_bf16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8bf16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z28test_svwrite_za16_bf16_vg1x4j14svbfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8bf16.nxv32bf16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8bf16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_bf16_vg1x4(uint32_t base, svbfloat16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_bf16,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za16_f16_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 16) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 24) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8f16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za16_f16_vg1x4j13svfloat16x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 16) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv8f16.nxv32f16( [[VAL]], i64 24) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv8f16(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za16_f16_vg1x4(uint32_t base, svfloat16x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za16,_f16,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za32_s32_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za32_s32_vg1x4j11svint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za32_s32_vg1x4(uint32_t base, svint32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za32,_s32,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za32_u32_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za32_u32_vg1x4j12svuint32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv16i32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv4i32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za32_u32_vg1x4(uint32_t base, svuint32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za32,_u32,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za32_f32_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 8) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 12) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv4f32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za32_f32_vg1x4j13svfloat32x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 8) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv4f32.nxv16f32( [[VAL]], i64 12) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv4f32(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za32_f32_vg1x4(uint32_t base, svfloat32x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za32,_f32,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za64_u64_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za64_u64_vg1x4j12svuint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za64_u64_vg1x4(uint32_t base, svuint64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za64,_u64,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za64_f64_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv2f64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za64_f64_vg1x4j13svfloat64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2f64.nxv8f64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv2f64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za64_f64_vg1x4(uint32_t base, svfloat64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za64,_f64,_vg1x4,)(base, val); +} + +// CHECK-LABEL: @test_svwrite_za64_s64_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z27test_svwrite_za64_s64_vg1x4j11svint64x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 2) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 4) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.extract.nxv2i64.nxv8i64( [[VAL]], i64 6) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv2i64(i32 [[BASE:%.*]], [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za64_s64_vg1x4(uint32_t base, svint64x4_t val) __arm_streaming __arm_shared_za { + SVE_ACLE_FUNC(svwrite_za64,_s64,_vg1x4,)(base, val); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_revd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_revd.c index 9d912c5d9e2767c750accd3ed69599e74fed197b..74a90583a173a59b3178e93568bf97a5403ebe67 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_revd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_revd.c @@ -1,14 +1,15 @@ // 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 +sve2p1 -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: -target-feature +sme -S -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 +sve2p1 -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu \ // RUN: -target-feature +sve2p1 -S -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 +sve2p1 -S -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK - +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -target-feature +bf16 -S -disable-O0-optnone -Werror -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +bf16 -S -disable-O0-optnone -Werror -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -388,3 +389,196 @@ svuint32_t test_svrevd_u32_x(svbool_t pg, svuint32_t op) { svuint64_t test_svrevd_u64_x(svbool_t pg, svuint64_t op) { return SVE_ACLE_FUNC(svrevd, _u64, _x, )(pg, op); } + + +// CHECK-LABEL: @test_svrevd_bf16_z( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8bf16( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svrevd_bf16_zu10__SVBool_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8bf16( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svbfloat16_t test_svrevd_bf16_z(svbool_t pg, svbfloat16_t op) { + return SVE_ACLE_FUNC(svrevd, _bf16, _z, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_f16_z( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8f16( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f16_zu10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8f16( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat16_t test_svrevd_f16_z(svbool_t pg, svfloat16_t op) { + return SVE_ACLE_FUNC(svrevd, _f16, _z, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_f32_z( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv4f32( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f32_zu10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv4f32( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat32_t test_svrevd_f32_z(svbool_t pg, svfloat32_t op) { + return SVE_ACLE_FUNC(svrevd, _f32, _z, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_f64_z( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv2f64( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f64_zu10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv2f64( zeroinitializer, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat64_t test_svrevd_f64_z(svbool_t pg, svfloat64_t op) { + return SVE_ACLE_FUNC(svrevd, _f64, _z, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_bf16_m( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8bf16( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svrevd_bf16_mu14__SVBfloat16_tu10__SVBool_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8bf16( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svbfloat16_t test_svrevd_bf16_m(svbfloat16_t inactive, svbool_t pg, svbfloat16_t op) { + return SVE_ACLE_FUNC(svrevd, _bf16, _m, )(inactive, pg, op); +} + +// CHECK-LABEL: @test_svrevd_f16_m( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8f16( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f16_mu13__SVFloat16_tu10__SVBool_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8f16( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat16_t test_svrevd_f16_m(svfloat16_t inactive, svbool_t pg, svfloat16_t op) { + return SVE_ACLE_FUNC(svrevd, _f16, _m, )(inactive, pg, op); +} + +// CHECK-LABEL: @test_svrevd_f32_m( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv4f32( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f32_mu13__SVFloat32_tu10__SVBool_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv4f32( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat32_t test_svrevd_f32_m(svfloat32_t inactive, svbool_t pg, svfloat32_t op) { + return SVE_ACLE_FUNC(svrevd, _f32, _m, )(inactive, pg, op); +} + +// CHECK-LABEL: @test_svrevd_f64_m( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv2f64( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f64_mu13__SVFloat64_tu10__SVBool_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv2f64( [[INACTIVE:%.*]], [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat64_t test_svrevd_f64_m(svfloat64_t inactive, svbool_t pg, svfloat64_t op) { + return SVE_ACLE_FUNC(svrevd, _f64, _m, )(inactive, pg, op); +} + +// CHECK-LABEL: @test_svrevd_bf16_x( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8bf16( undef, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svrevd_bf16_xu10__SVBool_tu14__SVBfloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8bf16( undef, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svbfloat16_t test_svrevd_bf16_x(svbool_t pg, svbfloat16_t op) { + return SVE_ACLE_FUNC(svrevd, _bf16, _x, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_f16_x( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8f16( undef, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f16_xu10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv8f16( undef, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat16_t test_svrevd_f16_x(svbool_t pg, svfloat16_t op) { + return SVE_ACLE_FUNC(svrevd, _f16, _x, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_f32_x( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv4f32( undef, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f32_xu10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv4f32( undef, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat32_t test_svrevd_f32_x(svbool_t pg, svfloat32_t op) { + return SVE_ACLE_FUNC(svrevd, _f32, _x, )(pg, op); +} + +// CHECK-LABEL: @test_svrevd_f64_x( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv2f64( undef, [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_f64_xu10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.revd.nxv2f64( undef, [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP1]] +// +svfloat64_t test_svrevd_f64_x(svbool_t pg, svfloat64_t op) { + return SVE_ACLE_FUNC(svrevd, _f64, _x, )(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfadd.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfadd.c index 327c4f078872b3c46ac94fa2709ce98f7c88af7b..2af8995b6fc9b93dbf85e526a417c3d04a4103a8 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfadd.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfadd.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fadd.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svadd_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svadd_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svadd, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svadd_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fadd.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svadd_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svadd_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svadd, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svadd_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fadd.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svadd_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svadd_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svadd, _bf16, _x)(pg, op1, op2); } @@ -83,7 +84,7 @@ svbfloat16_t test_svadd_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fadd.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svadd_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svadd_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svadd, _n_bf16, _m)(pg, op1, op2); } @@ -106,7 +107,7 @@ svbfloat16_t test_svadd_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fadd.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svadd_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svadd_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svadd, _n_bf16, _z)(pg, op1, op2); } @@ -127,7 +128,7 @@ svbfloat16_t test_svadd_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fadd.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svadd_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svadd_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svadd, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmax.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmax.c index 0553b993622bde151b8cd0a0e2988279b30ffef6..b0534753b1be9329e63088a381b81a4ee3940fbf 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmax.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmax.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmax.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmax_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmax_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmax, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svmax_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmax.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmax_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmax_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmax, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svmax_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmax.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmax_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmax_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmax, _bf16, _x)(pg, op1, op2); } @@ -84,7 +85,7 @@ svbfloat16_t test_svmax_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmax.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmax_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmax_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmax, _n_bf16, _m)(pg, op1, op2); } @@ -107,7 +108,7 @@ svbfloat16_t test_svmax_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmax.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmax_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmax_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmax, _n_bf16, _z)(pg, op1, op2); } @@ -128,7 +129,7 @@ svbfloat16_t test_svmax_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmax.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmax_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmax_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmax, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmaxnm.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmaxnm.c index fbbafde686edba00ad3dd798f163ecd9e7478132..ddf0a5711bab92e51f0ed263a00dcadd4c2a49a2 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmaxnm.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmaxnm.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmaxnm.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmaxnm_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmaxnm_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmaxnm, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svmaxnm_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmaxnm.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmaxnm_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmaxnm_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmaxnm, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svmaxnm_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmaxnm.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmaxnm_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmaxnm_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmaxnm, _bf16, _x)(pg, op1, op2); } @@ -84,7 +85,7 @@ svbfloat16_t test_svmaxnm_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmaxnm.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmaxnm_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmaxnm_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmaxnm, _n_bf16, _m)(pg, op1, op2); } @@ -107,7 +108,7 @@ svbfloat16_t test_svmaxnm_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2 // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmaxnm.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmaxnm_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmaxnm_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmaxnm, _n_bf16, _z)(pg, op1, op2); } @@ -128,7 +129,7 @@ svbfloat16_t test_svmaxnm_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmaxnm.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmaxnm_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmaxnm_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmaxnm, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmin.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmin.c index bf774ee0cef661683c1485ddb1a976458565c065..42d29e6dbc395433a73039672ae47d5b7583c95a 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmin.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmin.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmin.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmin_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmin_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmin, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svmin_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmin.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmin_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmin_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmin, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svmin_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmin.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmin_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmin_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmin, _bf16, _x)(pg, op1, op2); } @@ -84,7 +85,7 @@ svbfloat16_t test_svmin_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmin.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmin_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmin_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmin, _n_bf16, _m)(pg, op1, op2); } @@ -107,7 +108,7 @@ svbfloat16_t test_svmin_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmin.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmin_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmin_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmin, _n_bf16, _z)(pg, op1, op2); } @@ -128,7 +129,7 @@ svbfloat16_t test_svmin_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmin.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmin_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmin_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmin, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfminnm.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfminnm.c index cf00f0d504522bb2f0d9bd2f77f22dd6c45525ec..27d85374aadcd348a91861a7a028613efad338e5 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfminnm.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfminnm.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fminnm.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svminnm_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svminnm_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svminnm, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svminnm_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fminnm.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svminnm_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svminnm_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svminnm, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svminnm_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fminnm.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svminnm_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svminnm_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svminnm, _bf16, _x)(pg, op1, op2); } @@ -84,7 +85,7 @@ svbfloat16_t test_svminnm_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fminnm.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svminnm_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svminnm_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svminnm, _n_bf16, _m)(pg, op1, op2); } @@ -107,7 +108,7 @@ svbfloat16_t test_svminnm_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2 // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fminnm.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svminnm_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svminnm_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svminnm, _n_bf16, _z)(pg, op1, op2); } @@ -128,7 +129,7 @@ svbfloat16_t test_svminnm_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fminnm.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svminnm_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svminnm_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svminnm, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmla.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmla.c index 0e1532563f8bb8138695dd2994df0214087d70d1..4928147767d80d8166a4b82094ba67bbd15cf242 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmla.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmla.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmla.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[OP3:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmla_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) +svbfloat16_t test_svmla_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmla, _bf16, _m)(pg, op1, op2, op3); } @@ -45,7 +46,7 @@ svbfloat16_t test_svmla_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmla.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]], [[OP3:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmla_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) +svbfloat16_t test_svmla_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmla, _bf16, _z)(pg, op1, op2, op3); } @@ -62,7 +63,7 @@ svbfloat16_t test_svmla_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmla.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[OP3:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmla_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) +svbfloat16_t test_svmla_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmla, _bf16, _x)(pg, op1, op2, op3); } @@ -83,7 +84,7 @@ svbfloat16_t test_svmla_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmla.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmla_n_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) +svbfloat16_t test_svmla_n_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmla, _n_bf16, _m)(pg, op1, op2, op3); } @@ -106,7 +107,7 @@ svbfloat16_t test_svmla_n_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmla.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmla_n_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) +svbfloat16_t test_svmla_n_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmla, _n_bf16, _z)(pg, op1, op2, op3); } @@ -127,7 +128,7 @@ svbfloat16_t test_svmla_n_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmla.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmla_n_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) +svbfloat16_t test_svmla_n_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmla, _n_bf16, _x)(pg, op1, op2, op3); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmls.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmls.c index b7d576ea01df6fdfb95679cf7fb24956ea9297a6..e952d1b17ae8cd0540b2203e178479af8c62cd2e 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmls.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmls.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmls.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[OP3:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmls_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) +svbfloat16_t test_svmls_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmls, _bf16, _m)(pg, op1, op2, op3); } @@ -45,7 +46,7 @@ svbfloat16_t test_svmls_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmls.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]], [[OP3:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmls_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) +svbfloat16_t test_svmls_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmls, _bf16, _z)(pg, op1, op2, op3); } @@ -62,7 +63,7 @@ svbfloat16_t test_svmls_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmls.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[OP3:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmls_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) +svbfloat16_t test_svmls_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmls, _bf16, _x)(pg, op1, op2, op3); } @@ -83,7 +84,7 @@ svbfloat16_t test_svmls_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmls.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmls_n_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) +svbfloat16_t test_svmls_n_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmls, _n_bf16, _m)(pg, op1, op2, op3); } @@ -106,7 +107,7 @@ svbfloat16_t test_svmls_n_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmls.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmls_n_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) +svbfloat16_t test_svmls_n_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmls, _n_bf16, _z)(pg, op1, op2, op3); } @@ -127,7 +128,7 @@ svbfloat16_t test_svmls_n_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2 // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmls.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmls_n_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) +svbfloat16_t test_svmls_n_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, bfloat16_t op3) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmls, _n_bf16, _x)(pg, op1, op2, op3); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmlsl.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmlsl.c index 7e1763a63ec4e1d6d1724a373230ca1ccbc5bb3c..c1d14e16ad17b6da54aad9d27ce18a9c09b3fec9 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmlsl.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmlsl.c @@ -2,13 +2,22 @@ // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -S -DTEST_SME2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s // RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -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 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -S -DTEST_SME2 -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 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s // RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -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 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sve2p1 -target-feature -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -target-feature -S -DTEST_SME2 -disable-O0-optnone -Werror -Wall -o /dev/null %s #include +#ifndef TEST_SME2 +#define ATTR +#else +#define ATTR __arm_streaming_compatible +#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,A4_UNUSED) A1##A3 @@ -29,7 +38,7 @@ // CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.bfmlslb( [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]]) // CPP-CHECK-NEXT: ret [[TMP0]] // -svfloat32_t test_bfmlslb(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) +svfloat32_t test_bfmlslb(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) ATTR { return SVE_ACLE_FUNC(svbfmlslb,_f32,,)(zda, zn, zm); } @@ -45,7 +54,7 @@ svfloat32_t test_bfmlslb(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) // CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.bfmlslb.lane( [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) // CPP-CHECK-NEXT: ret [[TMP0]] // -svfloat32_t test_bfmlslb_lane(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) +svfloat32_t test_bfmlslb_lane(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) ATTR { return SVE_ACLE_FUNC(svbfmlslb_lane,_f32,,)(zda, zn, zm, 7); } @@ -63,7 +72,7 @@ svfloat32_t test_bfmlslb_lane(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) // CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.bfmlslt( [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]]) // CPP-CHECK-NEXT: ret [[TMP0]] // -svfloat32_t test_bfmlslt(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) +svfloat32_t test_bfmlslt(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) ATTR { return SVE_ACLE_FUNC(svbfmlslt,_f32,,)(zda, zn, zm); } @@ -79,7 +88,7 @@ svfloat32_t test_bfmlslt(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) // CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.bfmlslt.lane( [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i32 7) // CPP-CHECK-NEXT: ret [[TMP0]] // -svfloat32_t test_bfmlslt_lane(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) +svfloat32_t test_bfmlslt_lane(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) ATTR { return SVE_ACLE_FUNC(svbfmlslt_lane,_f32,,)(zda, zn, zm, 7); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmul.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmul.c index 8b0de974f2473bcb127176357030795501499f2e..078ea58408ad95f896d4d0ab01ff165d4eb2471c 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmul.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfmul.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmul.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmul_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmul_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmul, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svmul_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmul.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmul_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmul_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmul, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svmul_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmul.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmul_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svmul_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmul, _bf16, _x)(pg, op1, op2); } @@ -84,7 +85,7 @@ svbfloat16_t test_svmul_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmul.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmul_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmul_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmul, _n_bf16, _m)(pg, op1, op2); } @@ -107,7 +108,7 @@ svbfloat16_t test_svmul_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fmul.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svmul_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmul_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmul, _n_bf16, _z)(pg, op1, op2); } @@ -128,7 +129,7 @@ svbfloat16_t test_svmul_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fmul.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svmul_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svmul_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svmul, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfsub.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfsub.c index c5cdf7efa445b84ba3873dac78822a7ad682b3e6..442562e9ed20a590fc75990b7731f7764fab5af5 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfsub.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_bfsub.c @@ -1,10 +1,11 @@ // 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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -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 +sve2p1 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -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 +sve2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +b16b16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -26,7 +27,7 @@ // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fsub.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svsub_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svsub_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svsub, _bf16, _m)(pg, op1, op2); } @@ -45,7 +46,7 @@ svbfloat16_t test_svsub_bf16_m(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fsub.nxv8bf16( [[TMP0]], [[TMP1]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svsub_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svsub_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svsub, _bf16, _z)(pg, op1, op2); } @@ -62,7 +63,7 @@ svbfloat16_t test_svsub_bf16_z(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fsub.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[OP2:%.*]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svsub_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +svbfloat16_t test_svsub_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svsub, _bf16, _x)(pg, op1, op2); } @@ -84,7 +85,7 @@ svbfloat16_t test_svsub_bf16_x(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fsub.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svsub_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svsub_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svsub, _n_bf16, _m)(pg, op1, op2); } @@ -107,7 +108,7 @@ svbfloat16_t test_svsub_bf16_n_m(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.fsub.nxv8bf16( [[TMP0]], [[TMP1]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP2]] // -svbfloat16_t test_svsub_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svsub_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svsub, _n_bf16, _z)(pg, op1, op2); } @@ -128,7 +129,7 @@ svbfloat16_t test_svsub_bf16_n_z(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) // CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fsub.u.nxv8bf16( [[TMP0]], [[OP1:%.*]], [[DOTSPLAT]]) // CPP-CHECK-NEXT: ret [[TMP1]] // -svbfloat16_t test_svsub_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) +svbfloat16_t test_svsub_bf16_n_x(svbool_t pg, svbfloat16_t op1, bfloat16_t op2) __arm_streaming_compatible { return SVE_ACLE_FUNC(svsub, _n_bf16, _x)(pg, op1, op2); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_cntp.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_cntp.c index 18973a6467450a24202593ac15a12a4fb66c42b3..56b1d992622145cba625065466dc4f27de11f712 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_cntp.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_cntp.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fclamp.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fclamp.c index a9f482cab39698c725b2ec0cdb8095d04c289607..5d8c5b7b8a18c66a5ad705e8e3b9f6082797fe6f 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fclamp.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fclamp.c @@ -10,6 +10,8 @@ // RUN: -S -Werror -emit-llvm -disable-O0-optnone -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sve2p1 \ // RUN: -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve \ +// RUN: -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fp_reduce.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fp_reduce.c new file mode 100644 index 0000000000000000000000000000000000000000..e58cf4e49a37f92c8ca2db3d19db54beb5349430 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_fp_reduce.c @@ -0,0 +1,285 @@ +// 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 +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +#include +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +// FADDQV + +// CHECK-LABEL: @test_svaddqv_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.addqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <8 x half> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_f16u10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.addqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <8 x half> [[TMP1]] +// +float16x8_t test_svaddqv_f16(svbool_t pg, svfloat16_t op) +{ + return SVE_ACLE_FUNC(svaddqv,,_f16,)(pg, op); +} + +// CHECK-LABEL: @test_svaddqv_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.addqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <4 x float> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_f32u10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.addqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <4 x float> [[TMP1]] +// +float32x4_t test_svaddqv_f32(svbool_t pg, svfloat32_t op) +{ + return SVE_ACLE_FUNC(svaddqv,,_f32,)(pg, op); +} + +// CHECK-LABEL: @test_svaddqv_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.addqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <2 x double> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_f64u10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.addqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <2 x double> [[TMP1]] +// +float64x2_t test_svaddqv_f64(svbool_t pg, svfloat64_t op) +{ + return SVE_ACLE_FUNC(svaddqv,,_f64,)(pg, op); +} + + +// FMAXQV + +// CHECK-LABEL: @test_svmaxqv_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fmaxqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <8 x half> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_f16u10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fmaxqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <8 x half> [[TMP1]] +// +float16x8_t test_svmaxqv_f16(svbool_t pg, svfloat16_t op) +{ + return SVE_ACLE_FUNC(svmaxqv,,_f16,)(pg, op); +} + +// CHECK-LABEL: @test_svmaxqv_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fmaxqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <4 x float> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_f32u10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fmaxqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <4 x float> [[TMP1]] +// +float32x4_t test_svmaxqv_f32(svbool_t pg, svfloat32_t op) +{ + return SVE_ACLE_FUNC(svmaxqv,,_f32,)(pg, op); +} + +// CHECK-LABEL: @test_svmaxqv_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fmaxqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <2 x double> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_f64u10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fmaxqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <2 x double> [[TMP1]] +// +float64x2_t test_svmaxqv_f64(svbool_t pg, svfloat64_t op) +{ + return SVE_ACLE_FUNC(svmaxqv,,_f64,)(pg, op); +} + + +// FMINQV + +// CHECK-LABEL: @test_svminqv_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fminqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <8 x half> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_f16u10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fminqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <8 x half> [[TMP1]] +// +float16x8_t test_svminqv_f16(svbool_t pg, svfloat16_t op) +{ + return SVE_ACLE_FUNC(svminqv,,_f16,)(pg, op); +} + +// CHECK-LABEL: @test_svminqv_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fminqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <4 x float> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_f32u10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fminqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <4 x float> [[TMP1]] +// +float32x4_t test_svminqv_f32(svbool_t pg, svfloat32_t op) +{ + return SVE_ACLE_FUNC(svminqv,,_f32,)(pg, op); +} + +// CHECK-LABEL: @test_svminqv_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fminqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <2 x double> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_f64u10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fminqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <2 x double> [[TMP1]] +// +float64x2_t test_svminqv_f64(svbool_t pg, svfloat64_t op) +{ + return SVE_ACLE_FUNC(svminqv,,_f64,)(pg, op); +} + + +// FMAXNMQV + +// CHECK-LABEL: @test_svmaxnmqv_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fmaxnmqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <8 x half> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svmaxnmqv_f16u10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fmaxnmqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <8 x half> [[TMP1]] +// +float16x8_t test_svmaxnmqv_f16(svbool_t pg, svfloat16_t op) +{ + return SVE_ACLE_FUNC(svmaxnmqv,,_f16,)(pg, op); +} + +// CHECK-LABEL: @test_svmaxnmqv_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fmaxnmqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <4 x float> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svmaxnmqv_f32u10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fmaxnmqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <4 x float> [[TMP1]] +// +float32x4_t test_svmaxnmqv_f32(svbool_t pg, svfloat32_t op) +{ + return SVE_ACLE_FUNC(svmaxnmqv,,_f32,)(pg, op); +} + +// CHECK-LABEL: @test_svmaxnmqv_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fmaxnmqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <2 x double> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svmaxnmqv_f64u10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fmaxnmqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <2 x double> [[TMP1]] +// +float64x2_t test_svmaxnmqv_f64(svbool_t pg, svfloat64_t op) +{ + return SVE_ACLE_FUNC(svmaxnmqv,,_f64,)(pg, op); +} + + +// FMINNMQV + +// CHECK-LABEL: @test_svminnmqv_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fminnmqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <8 x half> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svminnmqv_f16u10__SVBool_tu13__SVFloat16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.fminnmqv.v8f16.nxv8f16( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <8 x half> [[TMP1]] +// +float16x8_t test_svminnmqv_f16(svbool_t pg, svfloat16_t op) +{ + return SVE_ACLE_FUNC(svminnmqv,,_f16,)(pg, op); +} + +// CHECK-LABEL: @test_svminnmqv_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fminnmqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <4 x float> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svminnmqv_f32u10__SVBool_tu13__SVFloat32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.fminnmqv.v4f32.nxv4f32( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <4 x float> [[TMP1]] +// +float32x4_t test_svminnmqv_f32(svbool_t pg, svfloat32_t op) +{ + return SVE_ACLE_FUNC(svminnmqv,,_f32,)(pg, op); +} + +// CHECK-LABEL: @test_svminnmqv_f64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fminnmqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CHECK-NEXT: ret <2 x double> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z18test_svminnmqv_f64u10__SVBool_tu13__SVFloat64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.fminnmqv.v2f64.nxv2f64( [[TMP0]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret <2 x double> [[TMP1]] +// +float64x2_t test_svminnmqv_f64(svbool_t pg, svfloat64_t op) +{ + return SVE_ACLE_FUNC(svminnmqv,,_f64,)(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_int_reduce.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_int_reduce.c new file mode 100644 index 0000000000000000000000000000000000000000..b395b4d1323ed5ebf685cf62b1c8c38b273e1b32 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_int_reduce.c @@ -0,0 +1,783 @@ +// 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 +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -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,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + + +// ADDQV + +// CHECK-LABEL: @test_svaddqv_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.addqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svaddqv_s8u10__SVBool_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.addqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +int8x16_t test_svaddqv_s8(svbool_t pg, svint8_t op1) { + return SVE_ACLE_FUNC(svaddqv,_s8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.addqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_s16u10__SVBool_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.addqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +int16x8_t test_svaddqv_s16(svbool_t pg, svint16_t op1) { + return SVE_ACLE_FUNC(svaddqv,_s16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.addqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_s32u10__SVBool_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.addqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +int32x4_t test_svaddqv_s32(svbool_t pg, svint32_t op1) { + return SVE_ACLE_FUNC(svaddqv,_s32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_s64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.addqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_s64u10__SVBool_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.addqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +int64x2_t test_svaddqv_s64(svbool_t pg, svint64_t op1) { + return SVE_ACLE_FUNC(svaddqv,_s64,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.addqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svaddqv_u8u10__SVBool_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.addqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_svaddqv_u8(svbool_t pg, svuint8_t op1) { + return SVE_ACLE_FUNC(svaddqv,_u8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.addqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_u16u10__SVBool_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.addqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +uint16x8_t test_svaddqv_u16(svbool_t pg, svuint16_t op1) { + return SVE_ACLE_FUNC(svaddqv,_u16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.addqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_u32u10__SVBool_tu12__SVUint32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.addqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +uint32x4_t test_svaddqv_u32(svbool_t pg, svuint32_t op1) { + return SVE_ACLE_FUNC(svaddqv,_u32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svaddqv_u64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.addqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svaddqv_u64u10__SVBool_tu12__SVUint64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.addqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +uint64x2_t test_svaddqv_u64(svbool_t pg, svuint64_t op1) { + return SVE_ACLE_FUNC(svaddqv,_u64,,)(pg, op1); +} + + +// ANDQV + +// CHECK-LABEL: @test_svandqv_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.andqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svandqv_s8u10__SVBool_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.andqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +int8x16_t test_svandqv_s8(svbool_t pg, svint8_t op1) { + return SVE_ACLE_FUNC(svandqv,_s8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.andqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svandqv_s16u10__SVBool_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.andqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +int16x8_t test_svandqv_s16(svbool_t pg, svint16_t op1) { + return SVE_ACLE_FUNC(svandqv,_s16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.andqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svandqv_s32u10__SVBool_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.andqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +int32x4_t test_svandqv_s32(svbool_t pg, svint32_t op1) { + return SVE_ACLE_FUNC(svandqv,_s32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_s64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.andqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svandqv_s64u10__SVBool_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.andqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +int64x2_t test_svandqv_s64(svbool_t pg, svint64_t op1) { + return SVE_ACLE_FUNC(svandqv,_s64,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.andqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svandqv_u8u10__SVBool_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.andqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_svandqv_u8(svbool_t pg, svuint8_t op1) { + return SVE_ACLE_FUNC(svandqv,_u8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.andqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svandqv_u16u10__SVBool_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.andqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +uint16x8_t test_svandqv_u16(svbool_t pg, svuint16_t op1) { + return SVE_ACLE_FUNC(svandqv,_u16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.andqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svandqv_u32u10__SVBool_tu12__SVUint32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.andqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +uint32x4_t test_svandqv_u32(svbool_t pg, svuint32_t op1) { + return SVE_ACLE_FUNC(svandqv,_u32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svandqv_u64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.andqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svandqv_u64u10__SVBool_tu12__SVUint64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.andqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +uint64x2_t test_svandqv_u64(svbool_t pg, svuint64_t op1) { + return SVE_ACLE_FUNC(svandqv,_u64,,)(pg, op1); +} + + +// EORQV + +// CHECK-LABEL: @test_sveorqv_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.eorqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_sveorqv_s8u10__SVBool_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.eorqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +int8x16_t test_sveorqv_s8(svbool_t pg, svint8_t op1) { + return SVE_ACLE_FUNC(sveorqv,_s8,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.eorqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_sveorqv_s16u10__SVBool_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.eorqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +int16x8_t test_sveorqv_s16(svbool_t pg, svint16_t op1) { + return SVE_ACLE_FUNC(sveorqv,_s16,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.eorqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_sveorqv_s32u10__SVBool_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.eorqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +int32x4_t test_sveorqv_s32(svbool_t pg, svint32_t op1) { + return SVE_ACLE_FUNC(sveorqv,_s32,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_s64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.eorqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_sveorqv_s64u10__SVBool_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.eorqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +int64x2_t test_sveorqv_s64(svbool_t pg, svint64_t op1) { + return SVE_ACLE_FUNC(sveorqv,_s64,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.eorqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_sveorqv_u8u10__SVBool_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.eorqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_sveorqv_u8(svbool_t pg, svuint8_t op1) { + return SVE_ACLE_FUNC(sveorqv,_u8,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.eorqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_sveorqv_u16u10__SVBool_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.eorqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +uint16x8_t test_sveorqv_u16(svbool_t pg, svuint16_t op1) { + return SVE_ACLE_FUNC(sveorqv,_u16,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.eorqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_sveorqv_u32u10__SVBool_tu12__SVUint32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.eorqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +uint32x4_t test_sveorqv_u32(svbool_t pg, svuint32_t op1) { + return SVE_ACLE_FUNC(sveorqv,_u32,,)(pg, op1); +} + +// CHECK-LABEL: @test_sveorqv_u64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.eorqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_sveorqv_u64u10__SVBool_tu12__SVUint64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.eorqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +uint64x2_t test_sveorqv_u64(svbool_t pg, svuint64_t op1) { + return SVE_ACLE_FUNC(sveorqv,_u64,,)(pg, op1); +} + + +// ORQV + +// CHECK-LABEL: @test_svorqv_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.orqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z14test_svorqv_s8u10__SVBool_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.orqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +int8x16_t test_svorqv_s8(svbool_t pg, svint8_t op1) { + return SVE_ACLE_FUNC(svorqv,_s8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.orqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z15test_svorqv_s16u10__SVBool_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.orqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +int16x8_t test_svorqv_s16(svbool_t pg, svint16_t op1) { + return SVE_ACLE_FUNC(svorqv,_s16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.orqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z15test_svorqv_s32u10__SVBool_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.orqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +int32x4_t test_svorqv_s32(svbool_t pg, svint32_t op1) { + return SVE_ACLE_FUNC(svorqv,_s32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_s64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.orqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z15test_svorqv_s64u10__SVBool_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.orqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +int64x2_t test_svorqv_s64(svbool_t pg, svint64_t op1) { + return SVE_ACLE_FUNC(svorqv,_s64,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.orqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z14test_svorqv_u8u10__SVBool_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.orqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_svorqv_u8(svbool_t pg, svuint8_t op1) { + return SVE_ACLE_FUNC(svorqv,_u8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.orqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z15test_svorqv_u16u10__SVBool_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.orqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +uint16x8_t test_svorqv_u16(svbool_t pg, svuint16_t op1) { + return SVE_ACLE_FUNC(svorqv,_u16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.orqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z15test_svorqv_u32u10__SVBool_tu12__SVUint32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.orqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +uint32x4_t test_svorqv_u32(svbool_t pg, svuint32_t op1) { + return SVE_ACLE_FUNC(svorqv,_u32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svorqv_u64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.orqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z15test_svorqv_u64u10__SVBool_tu12__SVUint64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.orqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +uint64x2_t test_svorqv_u64(svbool_t pg, svuint64_t op1) { + return SVE_ACLE_FUNC(svorqv,_u64,,)(pg, op1); +} + + +// SMAXQV + +// CHECK-LABEL: @test_svmaxqv_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.smaxqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svmaxqv_s8u10__SVBool_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.smaxqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +int8x16_t test_svmaxqv_s8(svbool_t pg, svint8_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_s8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svmaxqv_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.smaxqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_s16u10__SVBool_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.smaxqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +int16x8_t test_svmaxqv_s16(svbool_t pg, svint16_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_s16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svmaxqv_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.smaxqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_s32u10__SVBool_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.smaxqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +int32x4_t test_svmaxqv_s32(svbool_t pg, svint32_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_s32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svmaxqv_s64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.smaxqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_s64u10__SVBool_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.smaxqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +int64x2_t test_svmaxqv_s64(svbool_t pg, svint64_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_s64,,)(pg, op1); +} + + +// UMAXQV + +// CHECK-LABEL: @test_svmaxqv_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.umaxqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svmaxqv_u8u10__SVBool_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.umaxqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_svmaxqv_u8(svbool_t pg, svuint8_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_u8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svmaxqv_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.umaxqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_u16u10__SVBool_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.umaxqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +uint16x8_t test_svmaxqv_u16(svbool_t pg, svuint16_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_u16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svmaxqv_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.umaxqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_u32u10__SVBool_tu12__SVUint32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.umaxqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +uint32x4_t test_svmaxqv_u32(svbool_t pg, svuint32_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_u32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svmaxqv_u64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.umaxqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svmaxqv_u64u10__SVBool_tu12__SVUint64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.umaxqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +uint64x2_t test_svmaxqv_u64(svbool_t pg, svuint64_t op1) { + return SVE_ACLE_FUNC(svmaxqv,_u64,,)(pg, op1); +} + + +// SMINQV + +// CHECK-LABEL: @test_svminqv_s8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.sminqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svminqv_s8u10__SVBool_tu10__SVInt8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.sminqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +int8x16_t test_svminqv_s8(svbool_t pg, svint8_t op1) { + return SVE_ACLE_FUNC(svminqv,_s8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svminqv_s16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.sminqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_s16u10__SVBool_tu11__SVInt16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.sminqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +int16x8_t test_svminqv_s16(svbool_t pg, svint16_t op1) { + return SVE_ACLE_FUNC(svminqv,_s16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svminqv_s32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.sminqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_s32u10__SVBool_tu11__SVInt32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.sminqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +int32x4_t test_svminqv_s32(svbool_t pg, svint32_t op1) { + return SVE_ACLE_FUNC(svminqv,_s32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svminqv_s64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.sminqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_s64u10__SVBool_tu11__SVInt64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.sminqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +int64x2_t test_svminqv_s64(svbool_t pg, svint64_t op1) { + return SVE_ACLE_FUNC(svminqv,_s64,,)(pg, op1); +} + + +// UMINQV + +// CHECK-LABEL: @test_svminqv_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.uminqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_svminqv_u8u10__SVBool_tu11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.aarch64.sve.uminqv.v16i8.nxv16i8( [[PG:%.*]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +uint8x16_t test_svminqv_u8(svbool_t pg, svuint8_t op1) { + return SVE_ACLE_FUNC(svminqv,_u8,,)(pg, op1); +} + +// CHECK-LABEL: @test_svminqv_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.uminqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_u16u10__SVBool_tu12__SVUint16_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x i16> @llvm.aarch64.sve.uminqv.v8i16.nxv8i16( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <8 x i16> [[TMP1]] +// +uint16x8_t test_svminqv_u16(svbool_t pg, svuint16_t op1) { + return SVE_ACLE_FUNC(svminqv,_u16,,)(pg, op1); +} + +// CHECK-LABEL: @test_svminqv_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.uminqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_u32u10__SVBool_tu12__SVUint32_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x i32> @llvm.aarch64.sve.uminqv.v4i32.nxv4i32( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <4 x i32> [[TMP1]] +// +uint32x4_t test_svminqv_u32(svbool_t pg, svuint32_t op1) { + return SVE_ACLE_FUNC(svminqv,_u32,,)(pg, op1); +} + +// CHECK-LABEL: @test_svminqv_u64( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.uminqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +// CPP-CHECK-LABEL: @_Z16test_svminqv_u64u10__SVBool_tu12__SVUint64_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[PG:%.*]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i64> @llvm.aarch64.sve.uminqv.v2i64.nxv2i64( [[TMP0]], [[OP1:%.*]]) +// CPP-CHECK-NEXT: ret <2 x i64> [[TMP1]] +// +uint64x2_t test_svminqv_u64(svbool_t pg, svuint64_t op1) { + return SVE_ACLE_FUNC(svminqv,_u64,,)(pg, op1); +} diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ld1.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ld1.c index 7a25d31de0130e0763383fb90e020e42b5dfd924..6f1231e776aa351c4e882faa400dcafbbb9d29d3 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ld1.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ld1.c @@ -1,9 +1,12 @@ // 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 +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + #include #ifdef SVE_OVERLOADED_FORMS @@ -13,6 +16,12 @@ #define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 #endif +#ifndef TEST_SME2 +#define ATTR +#else +#define ATTR __arm_streaming +#endif + // CHECK-LABEL: @test_svld1_u8_x2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.ld1.pn.x2.nxv16i8(target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) @@ -31,7 +40,7 @@ // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint8x2_t test_svld1_u8_x2(svcount_t pn, const uint8_t *base) +svuint8x2_t test_svld1_u8_x2(svcount_t pn, const uint8_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u8,_x2,)(pn, base); } @@ -54,7 +63,7 @@ svuint8x2_t test_svld1_u8_x2(svcount_t pn, const uint8_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint16x2_t test_svld1_u16_x2(svcount_t pn, const uint16_t *base) +svuint16x2_t test_svld1_u16_x2(svcount_t pn, const uint16_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u16,_x2,)(pn, base); } @@ -77,7 +86,7 @@ svuint16x2_t test_svld1_u16_x2(svcount_t pn, const uint16_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint32x2_t test_svld1_u32_x2(svcount_t pn, const uint32_t *base) +svuint32x2_t test_svld1_u32_x2(svcount_t pn, const uint32_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u32,_x2,)(pn, base); } @@ -100,7 +109,7 @@ svuint32x2_t test_svld1_u32_x2(svcount_t pn, const uint32_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint64x2_t test_svld1_u64_x2(svcount_t pn, const uint64_t *base) +svuint64x2_t test_svld1_u64_x2(svcount_t pn, const uint64_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u64,_x2,)(pn, base); } @@ -131,7 +140,7 @@ svuint64x2_t test_svld1_u64_x2(svcount_t pn, const uint64_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint8x4_t test_svld1_u8_x4(svcount_t pn, const uint8_t *base) +svuint8x4_t test_svld1_u8_x4(svcount_t pn, const uint8_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u8,_x4,)(pn, base); } @@ -162,7 +171,7 @@ svuint8x4_t test_svld1_u8_x4(svcount_t pn, const uint8_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint16x4_t test_svld1_u16_x4(svcount_t pn, const uint16_t *base) +svuint16x4_t test_svld1_u16_x4(svcount_t pn, const uint16_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u16,_x4,)(pn, base); } @@ -193,7 +202,7 @@ svuint16x4_t test_svld1_u16_x4(svcount_t pn, const uint16_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint32x4_t test_svld1_u32_x4(svcount_t pn, const uint32_t *base) +svuint32x4_t test_svld1_u32_x4(svcount_t pn, const uint32_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u32,_x4,)(pn, base); } @@ -224,7 +233,7 @@ svuint32x4_t test_svld1_u32_x4(svcount_t pn, const uint32_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint64x4_t test_svld1_u64_x4(svcount_t pn, const uint64_t *base) +svuint64x4_t test_svld1_u64_x4(svcount_t pn, const uint64_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_u64,_x4,)(pn, base); } @@ -247,7 +256,7 @@ svuint64x4_t test_svld1_u64_x4(svcount_t pn, const uint64_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint8x2_t test_svld1_s8_x2(svcount_t pn, const int8_t *base) +svint8x2_t test_svld1_s8_x2(svcount_t pn, const int8_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s8,_x2,)(pn, base); } @@ -270,7 +279,7 @@ svint8x2_t test_svld1_s8_x2(svcount_t pn, const int8_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint16x2_t test_svld1_s16_x2(svcount_t pn, const int16_t *base) +svint16x2_t test_svld1_s16_x2(svcount_t pn, const int16_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s16,_x2,)(pn, base); } @@ -293,7 +302,7 @@ svint16x2_t test_svld1_s16_x2(svcount_t pn, const int16_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint32x2_t test_svld1_s32_x2(svcount_t pn, const int32_t *base) +svint32x2_t test_svld1_s32_x2(svcount_t pn, const int32_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s32,_x2,)(pn, base); } @@ -316,7 +325,7 @@ svint32x2_t test_svld1_s32_x2(svcount_t pn, const int32_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint64x2_t test_svld1_s64_x2(svcount_t pn, const int64_t *base) +svint64x2_t test_svld1_s64_x2(svcount_t pn, const int64_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s64,_x2,)(pn, base); } @@ -347,7 +356,7 @@ svint64x2_t test_svld1_s64_x2(svcount_t pn, const int64_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint8x4_t test_svld1_s8_x4(svcount_t pn, const int8_t *base) +svint8x4_t test_svld1_s8_x4(svcount_t pn, const int8_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s8,_x4,)(pn, base); } @@ -378,7 +387,7 @@ svint8x4_t test_svld1_s8_x4(svcount_t pn, const int8_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint16x4_t test_svld1_s16_x4(svcount_t pn, const int16_t *base) +svint16x4_t test_svld1_s16_x4(svcount_t pn, const int16_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s16,_x4,)(pn, base); } @@ -409,7 +418,7 @@ svint16x4_t test_svld1_s16_x4(svcount_t pn, const int16_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint32x4_t test_svld1_s32_x4(svcount_t pn, const int32_t *base) +svint32x4_t test_svld1_s32_x4(svcount_t pn, const int32_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s32,_x4,)(pn, base); } @@ -440,7 +449,7 @@ svint32x4_t test_svld1_s32_x4(svcount_t pn, const int32_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint64x4_t test_svld1_s64_x4(svcount_t pn, const int64_t *base) +svint64x4_t test_svld1_s64_x4(svcount_t pn, const int64_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_s64,_x4,)(pn, base); } @@ -463,7 +472,7 @@ svint64x4_t test_svld1_s64_x4(svcount_t pn, const int64_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) // CPP-CHECK-NEXT: ret [[TMP4]] // -svfloat16x2_t test_svld1_f16_x2(svcount_t pn, const float16_t *base) +svfloat16x2_t test_svld1_f16_x2(svcount_t pn, const float16_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_f16,_x2,)(pn, base); } @@ -486,7 +495,7 @@ svfloat16x2_t test_svld1_f16_x2(svcount_t pn, const float16_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) // CPP-CHECK-NEXT: ret [[TMP4]] // -svfloat32x2_t test_svld1_f32_x2(svcount_t pn, const float32_t *base) +svfloat32x2_t test_svld1_f32_x2(svcount_t pn, const float32_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_f32,_x2,)(pn, base); } @@ -509,7 +518,7 @@ svfloat32x2_t test_svld1_f32_x2(svcount_t pn, const float32_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) // CPP-CHECK-NEXT: ret [[TMP4]] // -svfloat64x2_t test_svld1_f64_x2(svcount_t pn, const float64_t *base) +svfloat64x2_t test_svld1_f64_x2(svcount_t pn, const float64_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_f64,_x2,)(pn, base); } @@ -540,7 +549,7 @@ svfloat64x2_t test_svld1_f64_x2(svcount_t pn, const float64_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) // CPP-CHECK-NEXT: ret [[TMP8]] // -svfloat16x4_t test_svld1_f16_x4(svcount_t pn, const float16_t *base) +svfloat16x4_t test_svld1_f16_x4(svcount_t pn, const float16_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_f16,_x4,)(pn, base); } @@ -571,7 +580,7 @@ svfloat16x4_t test_svld1_f16_x4(svcount_t pn, const float16_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) // CPP-CHECK-NEXT: ret [[TMP8]] // -svfloat32x4_t test_svld1_f32_x4(svcount_t pn, const float32_t *base) +svfloat32x4_t test_svld1_f32_x4(svcount_t pn, const float32_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_f32,_x4,)(pn, base); } @@ -602,7 +611,7 @@ svfloat32x4_t test_svld1_f32_x4(svcount_t pn, const float32_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) // CPP-CHECK-NEXT: ret [[TMP8]] // -svfloat64x4_t test_svld1_f64_x4(svcount_t pn, const float64_t *base) +svfloat64x4_t test_svld1_f64_x4(svcount_t pn, const float64_t *base) ATTR { return SVE_ACLE_FUNC(svld1,_f64,_x4,)(pn, base); } @@ -631,7 +640,7 @@ svfloat64x4_t test_svld1_f64_x4(svcount_t pn, const float64_t *base) // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP3]], [[TMP4]], i64 16) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint8x2_t test_svld1_vnum_u8_x2(svcount_t pn, const uint8_t *base, int64_t vnum) +svuint8x2_t test_svld1_vnum_u8_x2(svcount_t pn, const uint8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u8,_x2,)(pn, base, vnum); } @@ -656,7 +665,7 @@ svuint8x2_t test_svld1_vnum_u8_x2(svcount_t pn, const uint8_t *base, int64_t vnu // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP3]], [[TMP4]], i64 8) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint16x2_t test_svld1_vnum_u16_x2(svcount_t pn, const uint16_t *base, int64_t vnum) +svuint16x2_t test_svld1_vnum_u16_x2(svcount_t pn, const uint16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u16,_x2,)(pn, base, vnum); } @@ -681,7 +690,7 @@ svuint16x2_t test_svld1_vnum_u16_x2(svcount_t pn, const uint16_t *base, int64_t // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP3]], [[TMP4]], i64 4) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint32x2_t test_svld1_vnum_u32_x2(svcount_t pn, const uint32_t *base, int64_t vnum) +svuint32x2_t test_svld1_vnum_u32_x2(svcount_t pn, const uint32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u32,_x2,)(pn, base, vnum); } @@ -706,7 +715,7 @@ svuint32x2_t test_svld1_vnum_u32_x2(svcount_t pn, const uint32_t *base, int64_t // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP3]], [[TMP4]], i64 2) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint64x2_t test_svld1_vnum_u64_x2(svcount_t pn, const uint64_t *base, int64_t vnum) +svuint64x2_t test_svld1_vnum_u64_x2(svcount_t pn, const uint64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u64,_x2,)(pn, base, vnum); } @@ -739,7 +748,7 @@ svuint64x2_t test_svld1_vnum_u64_x2(svcount_t pn, const uint64_t *base, int64_t // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP7]], [[TMP8]], i64 48) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint8x4_t test_svld1_vnum_u8_x4(svcount_t pn, const uint8_t *base, int64_t vnum) +svuint8x4_t test_svld1_vnum_u8_x4(svcount_t pn, const uint8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u8,_x4,)(pn, base, vnum); } @@ -772,7 +781,7 @@ svuint8x4_t test_svld1_vnum_u8_x4(svcount_t pn, const uint8_t *base, int64_t vnu // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP7]], [[TMP8]], i64 24) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint16x4_t test_svld1_vnum_u16_x4(svcount_t pn, const uint16_t *base, int64_t vnum) +svuint16x4_t test_svld1_vnum_u16_x4(svcount_t pn, const uint16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u16,_x4,)(pn, base, vnum); } @@ -805,7 +814,7 @@ svuint16x4_t test_svld1_vnum_u16_x4(svcount_t pn, const uint16_t *base, int64_t // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP7]], [[TMP8]], i64 12) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint32x4_t test_svld1_vnum_u32_x4(svcount_t pn, const uint32_t *base, int64_t vnum) +svuint32x4_t test_svld1_vnum_u32_x4(svcount_t pn, const uint32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u32,_x4,)(pn, base, vnum); } @@ -838,7 +847,7 @@ svuint32x4_t test_svld1_vnum_u32_x4(svcount_t pn, const uint32_t *base, int64_t // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP7]], [[TMP8]], i64 6) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint64x4_t test_svld1_vnum_u64_x4(svcount_t pn, const uint64_t *base, int64_t vnum) +svuint64x4_t test_svld1_vnum_u64_x4(svcount_t pn, const uint64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_u64,_x4,)(pn, base, vnum); } @@ -863,7 +872,7 @@ svuint64x4_t test_svld1_vnum_u64_x4(svcount_t pn, const uint64_t *base, int64_t // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP3]], [[TMP4]], i64 16) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint8x2_t test_svld1_vnum_s8_x2(svcount_t pn, const int8_t *base, int64_t vnum) +svint8x2_t test_svld1_vnum_s8_x2(svcount_t pn, const int8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s8,_x2,)(pn, base, vnum); } @@ -888,7 +897,7 @@ svint8x2_t test_svld1_vnum_s8_x2(svcount_t pn, const int8_t *base, int64_t vnum) // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP3]], [[TMP4]], i64 8) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint16x2_t test_svld1_vnum_s16_x2(svcount_t pn, const int16_t *base, int64_t vnum) +svint16x2_t test_svld1_vnum_s16_x2(svcount_t pn, const int16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s16,_x2,)(pn, base, vnum); } @@ -913,7 +922,7 @@ svint16x2_t test_svld1_vnum_s16_x2(svcount_t pn, const int16_t *base, int64_t vn // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP3]], [[TMP4]], i64 4) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint32x2_t test_svld1_vnum_s32_x2(svcount_t pn, const int32_t *base, int64_t vnum) +svint32x2_t test_svld1_vnum_s32_x2(svcount_t pn, const int32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s32,_x2,)(pn, base, vnum); } @@ -938,7 +947,7 @@ svint32x2_t test_svld1_vnum_s32_x2(svcount_t pn, const int32_t *base, int64_t vn // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP3]], [[TMP4]], i64 2) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint64x2_t test_svld1_vnum_s64_x2(svcount_t pn, const int64_t *base, int64_t vnum) +svint64x2_t test_svld1_vnum_s64_x2(svcount_t pn, const int64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s64,_x2,)(pn, base, vnum); } @@ -971,7 +980,7 @@ svint64x2_t test_svld1_vnum_s64_x2(svcount_t pn, const int64_t *base, int64_t vn // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP7]], [[TMP8]], i64 48) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint8x4_t test_svld1_vnum_s8_x4(svcount_t pn, const int8_t *base, int64_t vnum) +svint8x4_t test_svld1_vnum_s8_x4(svcount_t pn, const int8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s8,_x4,)(pn, base, vnum); } @@ -1004,7 +1013,7 @@ svint8x4_t test_svld1_vnum_s8_x4(svcount_t pn, const int8_t *base, int64_t vnum) // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP7]], [[TMP8]], i64 24) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint16x4_t test_svld1_vnum_s16_x4(svcount_t pn, const int16_t *base, int64_t vnum) +svint16x4_t test_svld1_vnum_s16_x4(svcount_t pn, const int16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s16,_x4,)(pn, base, vnum); } @@ -1037,7 +1046,7 @@ svint16x4_t test_svld1_vnum_s16_x4(svcount_t pn, const int16_t *base, int64_t vn // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP7]], [[TMP8]], i64 12) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint32x4_t test_svld1_vnum_s32_x4(svcount_t pn, const int32_t *base, int64_t vnum) +svint32x4_t test_svld1_vnum_s32_x4(svcount_t pn, const int32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s32,_x4,)(pn, base, vnum); } @@ -1070,7 +1079,7 @@ svint32x4_t test_svld1_vnum_s32_x4(svcount_t pn, const int32_t *base, int64_t vn // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP7]], [[TMP8]], i64 6) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint64x4_t test_svld1_vnum_s64_x4(svcount_t pn, const int64_t *base, int64_t vnum) +svint64x4_t test_svld1_vnum_s64_x4(svcount_t pn, const int64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_s64,_x4,)(pn, base, vnum); } @@ -1095,7 +1104,7 @@ svint64x4_t test_svld1_vnum_s64_x4(svcount_t pn, const int64_t *base, int64_t vn // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP3]], [[TMP4]], i64 8) // CPP-CHECK-NEXT: ret [[TMP5]] // -svfloat16x2_t test_svld1_vnum_f16_x2(svcount_t pn, const float16_t *base, int64_t vnum) +svfloat16x2_t test_svld1_vnum_f16_x2(svcount_t pn, const float16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_f16,_x2,)(pn, base, vnum); } @@ -1120,7 +1129,7 @@ svfloat16x2_t test_svld1_vnum_f16_x2(svcount_t pn, const float16_t *base, int64_ // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP3]], [[TMP4]], i64 4) // CPP-CHECK-NEXT: ret [[TMP5]] // -svfloat32x2_t test_svld1_vnum_f32_x2(svcount_t pn, const float32_t *base, int64_t vnum) +svfloat32x2_t test_svld1_vnum_f32_x2(svcount_t pn, const float32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_f32,_x2,)(pn, base, vnum); } @@ -1145,7 +1154,7 @@ svfloat32x2_t test_svld1_vnum_f32_x2(svcount_t pn, const float32_t *base, int64_ // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP3]], [[TMP4]], i64 2) // CPP-CHECK-NEXT: ret [[TMP5]] // -svfloat64x2_t test_svld1_vnum_f64_x2(svcount_t pn, const float64_t *base, int64_t vnum) +svfloat64x2_t test_svld1_vnum_f64_x2(svcount_t pn, const float64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_f64,_x2,)(pn, base, vnum); } @@ -1178,7 +1187,7 @@ svfloat64x2_t test_svld1_vnum_f64_x2(svcount_t pn, const float64_t *base, int64_ // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP7]], [[TMP8]], i64 24) // CPP-CHECK-NEXT: ret [[TMP9]] // -svfloat16x4_t test_svld1_vnum_f16_x4(svcount_t pn, const float16_t *base, int64_t vnum) +svfloat16x4_t test_svld1_vnum_f16_x4(svcount_t pn, const float16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_f16,_x4,)(pn, base, vnum); } @@ -1211,7 +1220,7 @@ svfloat16x4_t test_svld1_vnum_f16_x4(svcount_t pn, const float16_t *base, int64_ // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP7]], [[TMP8]], i64 12) // CPP-CHECK-NEXT: ret [[TMP9]] // -svfloat32x4_t test_svld1_vnum_f32_x4(svcount_t pn, const float32_t *base, int64_t vnum) +svfloat32x4_t test_svld1_vnum_f32_x4(svcount_t pn, const float32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_f32,_x4,)(pn, base, vnum); } @@ -1244,7 +1253,7 @@ svfloat32x4_t test_svld1_vnum_f32_x4(svcount_t pn, const float32_t *base, int64_ // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP7]], [[TMP8]], i64 6) // CPP-CHECK-NEXT: ret [[TMP9]] // -svfloat64x4_t test_svld1_vnum_f64_x4(svcount_t pn, const float64_t *base, int64_t vnum) +svfloat64x4_t test_svld1_vnum_f64_x4(svcount_t pn, const float64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svld1_vnum,_f64,_x4,)(pn, base, vnum); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ldnt1.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ldnt1.c index 7a0fcde819dce0fd496e6d621ebfb87681d49b93..3f61cc3de139520ca9a936cec8d93280d0c969b1 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ldnt1.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ldnt1.c @@ -1,9 +1,12 @@ // 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 +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + #include #ifdef SVE_OVERLOADED_FORMS @@ -13,6 +16,12 @@ #define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 #endif +#ifndef TEST_SME2 +#define ATTR +#else +#define ATTR __arm_streaming +#endif + // CHECK-LABEL: @test_svldnt1_u8_x2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.ldnt1.pn.x2.nxv16i8(target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) @@ -31,7 +40,7 @@ // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint8x2_t test_svldnt1_u8_x2(svcount_t pn, const uint8_t *base) +svuint8x2_t test_svldnt1_u8_x2(svcount_t pn, const uint8_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u8,_x2,)(pn, base); } @@ -54,7 +63,7 @@ svuint8x2_t test_svldnt1_u8_x2(svcount_t pn, const uint8_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint16x2_t test_svldnt1_u16_x2(svcount_t pn, const uint16_t *base) +svuint16x2_t test_svldnt1_u16_x2(svcount_t pn, const uint16_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u16,_x2,)(pn, base); } @@ -77,7 +86,7 @@ svuint16x2_t test_svldnt1_u16_x2(svcount_t pn, const uint16_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint32x2_t test_svldnt1_u32_x2(svcount_t pn, const uint32_t *base) +svuint32x2_t test_svldnt1_u32_x2(svcount_t pn, const uint32_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u32,_x2,)(pn, base); } @@ -100,7 +109,7 @@ svuint32x2_t test_svldnt1_u32_x2(svcount_t pn, const uint32_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) // CPP-CHECK-NEXT: ret [[TMP4]] // -svuint64x2_t test_svldnt1_u64_x2(svcount_t pn, const uint64_t *base) +svuint64x2_t test_svldnt1_u64_x2(svcount_t pn, const uint64_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u64,_x2,)(pn, base); } @@ -131,7 +140,7 @@ svuint64x2_t test_svldnt1_u64_x2(svcount_t pn, const uint64_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint8x4_t test_svldnt1_u8_x4(svcount_t pn, const uint8_t *base) +svuint8x4_t test_svldnt1_u8_x4(svcount_t pn, const uint8_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u8,_x4,)(pn, base); } @@ -162,7 +171,7 @@ svuint8x4_t test_svldnt1_u8_x4(svcount_t pn, const uint8_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint16x4_t test_svldnt1_u16_x4(svcount_t pn, const uint16_t *base) +svuint16x4_t test_svldnt1_u16_x4(svcount_t pn, const uint16_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u16,_x4,)(pn, base); } @@ -193,7 +202,7 @@ svuint16x4_t test_svldnt1_u16_x4(svcount_t pn, const uint16_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint32x4_t test_svldnt1_u32_x4(svcount_t pn, const uint32_t *base) +svuint32x4_t test_svldnt1_u32_x4(svcount_t pn, const uint32_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u32,_x4,)(pn, base); } @@ -224,7 +233,7 @@ svuint32x4_t test_svldnt1_u32_x4(svcount_t pn, const uint32_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) // CPP-CHECK-NEXT: ret [[TMP8]] // -svuint64x4_t test_svldnt1_u64_x4(svcount_t pn, const uint64_t *base) +svuint64x4_t test_svldnt1_u64_x4(svcount_t pn, const uint64_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_u64,_x4,)(pn, base); } @@ -247,7 +256,7 @@ svuint64x4_t test_svldnt1_u64_x4(svcount_t pn, const uint64_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP2]], [[TMP3]], i64 16) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint8x2_t test_svldnt1_s8_x2(svcount_t pn, const int8_t *base) +svint8x2_t test_svldnt1_s8_x2(svcount_t pn, const int8_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s8,_x2,)(pn, base); } @@ -270,7 +279,7 @@ svint8x2_t test_svldnt1_s8_x2(svcount_t pn, const int8_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP2]], [[TMP3]], i64 8) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint16x2_t test_svldnt1_s16_x2(svcount_t pn, const int16_t *base) +svint16x2_t test_svldnt1_s16_x2(svcount_t pn, const int16_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s16,_x2,)(pn, base); } @@ -293,7 +302,7 @@ svint16x2_t test_svldnt1_s16_x2(svcount_t pn, const int16_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP2]], [[TMP3]], i64 4) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint32x2_t test_svldnt1_s32_x2(svcount_t pn, const int32_t *base) +svint32x2_t test_svldnt1_s32_x2(svcount_t pn, const int32_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s32,_x2,)(pn, base); } @@ -316,7 +325,7 @@ svint32x2_t test_svldnt1_s32_x2(svcount_t pn, const int32_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP2]], [[TMP3]], i64 2) // CPP-CHECK-NEXT: ret [[TMP4]] // -svint64x2_t test_svldnt1_s64_x2(svcount_t pn, const int64_t *base) +svint64x2_t test_svldnt1_s64_x2(svcount_t pn, const int64_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s64,_x2,)(pn, base); } @@ -347,7 +356,7 @@ svint64x2_t test_svldnt1_s64_x2(svcount_t pn, const int64_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP6]], [[TMP7]], i64 48) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint8x4_t test_svldnt1_s8_x4(svcount_t pn, const int8_t *base) +svint8x4_t test_svldnt1_s8_x4(svcount_t pn, const int8_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s8,_x4,)(pn, base); } @@ -378,7 +387,7 @@ svint8x4_t test_svldnt1_s8_x4(svcount_t pn, const int8_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP6]], [[TMP7]], i64 24) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint16x4_t test_svldnt1_s16_x4(svcount_t pn, const int16_t *base) +svint16x4_t test_svldnt1_s16_x4(svcount_t pn, const int16_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s16,_x4,)(pn, base); } @@ -409,7 +418,7 @@ svint16x4_t test_svldnt1_s16_x4(svcount_t pn, const int16_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP6]], [[TMP7]], i64 12) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint32x4_t test_svldnt1_s32_x4(svcount_t pn, const int32_t *base) +svint32x4_t test_svldnt1_s32_x4(svcount_t pn, const int32_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s32,_x4,)(pn, base); } @@ -440,7 +449,7 @@ svint32x4_t test_svldnt1_s32_x4(svcount_t pn, const int32_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP6]], [[TMP7]], i64 6) // CPP-CHECK-NEXT: ret [[TMP8]] // -svint64x4_t test_svldnt1_s64_x4(svcount_t pn, const int64_t *base) +svint64x4_t test_svldnt1_s64_x4(svcount_t pn, const int64_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_s64,_x4,)(pn, base); } @@ -463,7 +472,7 @@ svint64x4_t test_svldnt1_s64_x4(svcount_t pn, const int64_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP2]], [[TMP3]], i64 8) // CPP-CHECK-NEXT: ret [[TMP4]] // -svfloat16x2_t test_svldnt1_f16_x2(svcount_t pn, const float16_t *base) +svfloat16x2_t test_svldnt1_f16_x2(svcount_t pn, const float16_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_f16,_x2,)(pn, base); } @@ -486,7 +495,7 @@ svfloat16x2_t test_svldnt1_f16_x2(svcount_t pn, const float16_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP2]], [[TMP3]], i64 4) // CPP-CHECK-NEXT: ret [[TMP4]] // -svfloat32x2_t test_svldnt1_f32_x2(svcount_t pn, const float32_t *base) +svfloat32x2_t test_svldnt1_f32_x2(svcount_t pn, const float32_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_f32,_x2,)(pn, base); } @@ -509,7 +518,7 @@ svfloat32x2_t test_svldnt1_f32_x2(svcount_t pn, const float32_t *base) // CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP2]], [[TMP3]], i64 2) // CPP-CHECK-NEXT: ret [[TMP4]] // -svfloat64x2_t test_svldnt1_f64_x2(svcount_t pn, const float64_t *base) +svfloat64x2_t test_svldnt1_f64_x2(svcount_t pn, const float64_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_f64,_x2,)(pn, base); } @@ -540,7 +549,7 @@ svfloat64x2_t test_svldnt1_f64_x2(svcount_t pn, const float64_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP6]], [[TMP7]], i64 24) // CPP-CHECK-NEXT: ret [[TMP8]] // -svfloat16x4_t test_svldnt1_f16_x4(svcount_t pn, const float16_t *base) +svfloat16x4_t test_svldnt1_f16_x4(svcount_t pn, const float16_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_f16,_x4,)(pn, base); } @@ -571,7 +580,7 @@ svfloat16x4_t test_svldnt1_f16_x4(svcount_t pn, const float16_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP6]], [[TMP7]], i64 12) // CPP-CHECK-NEXT: ret [[TMP8]] // -svfloat32x4_t test_svldnt1_f32_x4(svcount_t pn, const float32_t *base) +svfloat32x4_t test_svldnt1_f32_x4(svcount_t pn, const float32_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_f32,_x4,)(pn, base); } @@ -602,7 +611,7 @@ svfloat32x4_t test_svldnt1_f32_x4(svcount_t pn, const float32_t *base) // CPP-CHECK-NEXT: [[TMP8:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP6]], [[TMP7]], i64 6) // CPP-CHECK-NEXT: ret [[TMP8]] // -svfloat64x4_t test_svldnt1_f64_x4(svcount_t pn, const float64_t *base) +svfloat64x4_t test_svldnt1_f64_x4(svcount_t pn, const float64_t *base) ATTR { return SVE_ACLE_FUNC(svldnt1,_f64,_x4,)(pn, base); } @@ -631,7 +640,7 @@ svfloat64x4_t test_svldnt1_f64_x4(svcount_t pn, const float64_t *base) // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP3]], [[TMP4]], i64 16) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint8x2_t test_svldnt1_vnum_u8_x2(svcount_t pn, const uint8_t *base, int64_t vnum) +svuint8x2_t test_svldnt1_vnum_u8_x2(svcount_t pn, const uint8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u8,_x2,)(pn, base, vnum); } @@ -656,7 +665,7 @@ svuint8x2_t test_svldnt1_vnum_u8_x2(svcount_t pn, const uint8_t *base, int64_t v // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP3]], [[TMP4]], i64 8) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint16x2_t test_svldnt1_vnum_u16_x2(svcount_t pn, const uint16_t *base, int64_t vnum) +svuint16x2_t test_svldnt1_vnum_u16_x2(svcount_t pn, const uint16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u16,_x2,)(pn, base, vnum); } @@ -681,7 +690,7 @@ svuint16x2_t test_svldnt1_vnum_u16_x2(svcount_t pn, const uint16_t *base, int64_ // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP3]], [[TMP4]], i64 4) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint32x2_t test_svldnt1_vnum_u32_x2(svcount_t pn, const uint32_t *base, int64_t vnum) +svuint32x2_t test_svldnt1_vnum_u32_x2(svcount_t pn, const uint32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u32,_x2,)(pn, base, vnum); } @@ -706,7 +715,7 @@ svuint32x2_t test_svldnt1_vnum_u32_x2(svcount_t pn, const uint32_t *base, int64_ // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP3]], [[TMP4]], i64 2) // CPP-CHECK-NEXT: ret [[TMP5]] // -svuint64x2_t test_svldnt1_vnum_u64_x2(svcount_t pn, const uint64_t *base, int64_t vnum) +svuint64x2_t test_svldnt1_vnum_u64_x2(svcount_t pn, const uint64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u64,_x2,)(pn, base, vnum); } @@ -739,7 +748,7 @@ svuint64x2_t test_svldnt1_vnum_u64_x2(svcount_t pn, const uint64_t *base, int64_ // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP7]], [[TMP8]], i64 48) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint8x4_t test_svldnt1_vnum_u8_x4(svcount_t pn, const uint8_t *base, int64_t vnum) +svuint8x4_t test_svldnt1_vnum_u8_x4(svcount_t pn, const uint8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u8,_x4,)(pn, base, vnum); } @@ -772,7 +781,7 @@ svuint8x4_t test_svldnt1_vnum_u8_x4(svcount_t pn, const uint8_t *base, int64_t v // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP7]], [[TMP8]], i64 24) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint16x4_t test_svldnt1_vnum_u16_x4(svcount_t pn, const uint16_t *base, int64_t vnum) +svuint16x4_t test_svldnt1_vnum_u16_x4(svcount_t pn, const uint16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u16,_x4,)(pn, base, vnum); } @@ -805,7 +814,7 @@ svuint16x4_t test_svldnt1_vnum_u16_x4(svcount_t pn, const uint16_t *base, int64_ // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP7]], [[TMP8]], i64 12) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint32x4_t test_svldnt1_vnum_u32_x4(svcount_t pn, const uint32_t *base, int64_t vnum) +svuint32x4_t test_svldnt1_vnum_u32_x4(svcount_t pn, const uint32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u32,_x4,)(pn, base, vnum); } @@ -838,7 +847,7 @@ svuint32x4_t test_svldnt1_vnum_u32_x4(svcount_t pn, const uint32_t *base, int64_ // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP7]], [[TMP8]], i64 6) // CPP-CHECK-NEXT: ret [[TMP9]] // -svuint64x4_t test_svldnt1_vnum_u64_x4(svcount_t pn, const uint64_t *base, int64_t vnum) +svuint64x4_t test_svldnt1_vnum_u64_x4(svcount_t pn, const uint64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_u64,_x4,)(pn, base, vnum); } @@ -863,7 +872,7 @@ svuint64x4_t test_svldnt1_vnum_u64_x4(svcount_t pn, const uint64_t *base, int64_ // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv32i8.nxv16i8( [[TMP3]], [[TMP4]], i64 16) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint8x2_t test_svldnt1_vnum_s8_x2(svcount_t pn, const int8_t *base, int64_t vnum) +svint8x2_t test_svldnt1_vnum_s8_x2(svcount_t pn, const int8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s8,_x2,)(pn, base, vnum); } @@ -888,7 +897,7 @@ svint8x2_t test_svldnt1_vnum_s8_x2(svcount_t pn, const int8_t *base, int64_t vnu // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv16i16.nxv8i16( [[TMP3]], [[TMP4]], i64 8) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint16x2_t test_svldnt1_vnum_s16_x2(svcount_t pn, const int16_t *base, int64_t vnum) +svint16x2_t test_svldnt1_vnum_s16_x2(svcount_t pn, const int16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s16,_x2,)(pn, base, vnum); } @@ -913,7 +922,7 @@ svint16x2_t test_svldnt1_vnum_s16_x2(svcount_t pn, const int16_t *base, int64_t // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv8i32.nxv4i32( [[TMP3]], [[TMP4]], i64 4) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint32x2_t test_svldnt1_vnum_s32_x2(svcount_t pn, const int32_t *base, int64_t vnum) +svint32x2_t test_svldnt1_vnum_s32_x2(svcount_t pn, const int32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s32,_x2,)(pn, base, vnum); } @@ -938,7 +947,7 @@ svint32x2_t test_svldnt1_vnum_s32_x2(svcount_t pn, const int32_t *base, int64_t // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv4i64.nxv2i64( [[TMP3]], [[TMP4]], i64 2) // CPP-CHECK-NEXT: ret [[TMP5]] // -svint64x2_t test_svldnt1_vnum_s64_x2(svcount_t pn, const int64_t *base, int64_t vnum) +svint64x2_t test_svldnt1_vnum_s64_x2(svcount_t pn, const int64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s64,_x2,)(pn, base, vnum); } @@ -971,7 +980,7 @@ svint64x2_t test_svldnt1_vnum_s64_x2(svcount_t pn, const int64_t *base, int64_t // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv64i8.nxv16i8( [[TMP7]], [[TMP8]], i64 48) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint8x4_t test_svldnt1_vnum_s8_x4(svcount_t pn, const int8_t *base, int64_t vnum) +svint8x4_t test_svldnt1_vnum_s8_x4(svcount_t pn, const int8_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s8,_x4,)(pn, base, vnum); } @@ -1004,7 +1013,7 @@ svint8x4_t test_svldnt1_vnum_s8_x4(svcount_t pn, const int8_t *base, int64_t vnu // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv32i16.nxv8i16( [[TMP7]], [[TMP8]], i64 24) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint16x4_t test_svldnt1_vnum_s16_x4(svcount_t pn, const int16_t *base, int64_t vnum) +svint16x4_t test_svldnt1_vnum_s16_x4(svcount_t pn, const int16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s16,_x4,)(pn, base, vnum); } @@ -1037,7 +1046,7 @@ svint16x4_t test_svldnt1_vnum_s16_x4(svcount_t pn, const int16_t *base, int64_t // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv16i32.nxv4i32( [[TMP7]], [[TMP8]], i64 12) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint32x4_t test_svldnt1_vnum_s32_x4(svcount_t pn, const int32_t *base, int64_t vnum) +svint32x4_t test_svldnt1_vnum_s32_x4(svcount_t pn, const int32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s32,_x4,)(pn, base, vnum); } @@ -1070,7 +1079,7 @@ svint32x4_t test_svldnt1_vnum_s32_x4(svcount_t pn, const int32_t *base, int64_t // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv8i64.nxv2i64( [[TMP7]], [[TMP8]], i64 6) // CPP-CHECK-NEXT: ret [[TMP9]] // -svint64x4_t test_svldnt1_vnum_s64_x4(svcount_t pn, const int64_t *base, int64_t vnum) +svint64x4_t test_svldnt1_vnum_s64_x4(svcount_t pn, const int64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_s64,_x4,)(pn, base, vnum); } @@ -1095,7 +1104,7 @@ svint64x4_t test_svldnt1_vnum_s64_x4(svcount_t pn, const int64_t *base, int64_t // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv16f16.nxv8f16( [[TMP3]], [[TMP4]], i64 8) // CPP-CHECK-NEXT: ret [[TMP5]] // -svfloat16x2_t test_svldnt1_vnum_f16_x2(svcount_t pn, const float16_t *base, int64_t vnum) +svfloat16x2_t test_svldnt1_vnum_f16_x2(svcount_t pn, const float16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_f16,_x2,)(pn, base, vnum); } @@ -1120,7 +1129,7 @@ svfloat16x2_t test_svldnt1_vnum_f16_x2(svcount_t pn, const float16_t *base, int6 // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv8f32.nxv4f32( [[TMP3]], [[TMP4]], i64 4) // CPP-CHECK-NEXT: ret [[TMP5]] // -svfloat32x2_t test_svldnt1_vnum_f32_x2(svcount_t pn, const float32_t *base, int64_t vnum) +svfloat32x2_t test_svldnt1_vnum_f32_x2(svcount_t pn, const float32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_f32,_x2,)(pn, base, vnum); } @@ -1145,7 +1154,7 @@ svfloat32x2_t test_svldnt1_vnum_f32_x2(svcount_t pn, const float32_t *base, int6 // CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.vector.insert.nxv4f64.nxv2f64( [[TMP3]], [[TMP4]], i64 2) // CPP-CHECK-NEXT: ret [[TMP5]] // -svfloat64x2_t test_svldnt1_vnum_f64_x2(svcount_t pn, const float64_t *base, int64_t vnum) +svfloat64x2_t test_svldnt1_vnum_f64_x2(svcount_t pn, const float64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_f64,_x2,)(pn, base, vnum); } @@ -1178,7 +1187,7 @@ svfloat64x2_t test_svldnt1_vnum_f64_x2(svcount_t pn, const float64_t *base, int6 // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv32f16.nxv8f16( [[TMP7]], [[TMP8]], i64 24) // CPP-CHECK-NEXT: ret [[TMP9]] // -svfloat16x4_t test_svldnt1_vnum_f16_x4(svcount_t pn, const float16_t *base, int64_t vnum) +svfloat16x4_t test_svldnt1_vnum_f16_x4(svcount_t pn, const float16_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_f16,_x4,)(pn, base, vnum); } @@ -1211,7 +1220,7 @@ svfloat16x4_t test_svldnt1_vnum_f16_x4(svcount_t pn, const float16_t *base, int6 // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv16f32.nxv4f32( [[TMP7]], [[TMP8]], i64 12) // CPP-CHECK-NEXT: ret [[TMP9]] // -svfloat32x4_t test_svldnt1_vnum_f32_x4(svcount_t pn, const float32_t *base, int64_t vnum) +svfloat32x4_t test_svldnt1_vnum_f32_x4(svcount_t pn, const float32_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_f32,_x4,)(pn, base, vnum); } @@ -1244,7 +1253,7 @@ svfloat32x4_t test_svldnt1_vnum_f32_x4(svcount_t pn, const float32_t *base, int6 // CPP-CHECK-NEXT: [[TMP9:%.*]] = tail call @llvm.vector.insert.nxv8f64.nxv2f64( [[TMP7]], [[TMP8]], i64 6) // CPP-CHECK-NEXT: ret [[TMP9]] // -svfloat64x4_t test_svldnt1_vnum_f64_x4(svcount_t pn, const float64_t *base, int64_t vnum) +svfloat64x4_t test_svldnt1_vnum_f64_x4(svcount_t pn, const float64_t *base, int64_t vnum) ATTR { return SVE_ACLE_FUNC(svldnt1_vnum,_f64,_x4,)(pn, base, vnum); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qcvtn.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qcvtn.c new file mode 100644 index 0000000000000000000000000000000000000000..fb53ea456c816abeadde1d4172caa6c0cc6250f8 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qcvtn.c @@ -0,0 +1,82 @@ +// 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 +sve2p1 -target-feature +bf16 -S -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 +sve2p1 -target-feature +bf16 -S -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 -D__SVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -D__SVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -target-feature +bf16 -S -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 +sve2p1 -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// RUN: %clang_cc1 -DTEST_SME2 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DTEST_SME2 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -target-feature +bf16 -S -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 -DTEST_SME2 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -target-feature +bf16 -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,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +#ifndef TEST_SME2 +#define ATTR +#else +#define ATTR __arm_streaming +#endif + +// CHECK-LABEL: @test_qcvtn_s16_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z21test_qcvtn_s16_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svint16_t test_qcvtn_s16_s32_x2(svint32x2_t zn) ATTR { + return SVE_ACLE_FUNC(svqcvtn_s16,_s32_x2,,)(zn); +} + +// CHECK-LABEL: @test_qcvtn_u16_u32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.uqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z21test_qcvtn_u16_u32_x212svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.uqcvtn.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svuint16_t test_qcvtn_u16_u32_x2(svuint32x2_t zn) ATTR { + return SVE_ACLE_FUNC(svqcvtn_u16,_u32_x2,,)(zn); +} + +// CHECK-LABEL: @test_qcvtn_u16_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtun.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z21test_qcvtn_u16_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqcvtun.x2.nxv4i32( [[TMP0]], [[TMP1]]) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svuint16_t test_qcvtn_u16_s32_x2(svint32x2_t zn) ATTR { + return SVE_ACLE_FUNC(svqcvtn_u16,_s32_x2,,)(zn); +} diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qrshr.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qrshr.c new file mode 100644 index 0000000000000000000000000000000000000000..6ebf224db92377cb7c398ece8b54c04876d167fe --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qrshr.c @@ -0,0 +1,79 @@ +// 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 +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -target-feature +sme-f64f64 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -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,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + + +// SQRSHRN x 2 + +// CHECK-LABEL: @test_svqrshrn_s16_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqrshrn.x2.nxv4i32( [[TMP0]], [[TMP1]], i32 16) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z24test_svqrshrn_s16_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqrshrn.x2.nxv4i32( [[TMP0]], [[TMP1]], i32 16) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svint16_t test_svqrshrn_s16_s32_x2(svint32x2_t zn) __arm_streaming_compatible { + return SVE_ACLE_FUNC(svqrshrn,_n,_s16,_s32_x2,)(zn, 16); +} + +// UQRSHRN x 2 + +// CHECK-LABEL: @test_svqrshrn_u16_u32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.uqrshrn.x2.nxv4i32( [[TMP0]], [[TMP1]], i32 16) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z24test_svqrshrn_u16_u32_x212svuint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.uqrshrn.x2.nxv4i32( [[TMP0]], [[TMP1]], i32 16) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svuint16_t test_svqrshrn_u16_u32_x2(svuint32x2_t zn) __arm_streaming_compatible { + return SVE_ACLE_FUNC(svqrshrn,_n,_u16,_u32_x2,)(zn, 16); +} + +// SQRSHRUN x 2 + +// CHECK-LABEL: @test_svqrshrun_u16_s32_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqrshrun.x2.nxv4i32( [[TMP0]], [[TMP1]], i32 16) +// CHECK-NEXT: ret [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z25test_svqrshrun_u16_s32_x211svint32x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN:%.*]], i64 0) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.vector.extract.nxv4i32.nxv8i32( [[ZN]], i64 4) +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.sqrshrun.x2.nxv4i32( [[TMP0]], [[TMP1]], i32 16) +// CPP-CHECK-NEXT: ret [[TMP2]] +// +svuint16_t test_svqrshrun_u16_s32_x2(svint32x2_t zn) __arm_streaming_compatible { + return SVE_ACLE_FUNC(svqrshrun,_n,_u16,_s32_x2,)(zn, 16); +} diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_st1.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_st1.c index 9efc37a1dd58e2a1f2bb9978c1b7542cb0876ae0..7aa994345a8c309c7d34ddd9ca37b9dbf29135d4 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_st1.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_st1.c @@ -1,9 +1,11 @@ // 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 +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include #ifdef SVE_OVERLOADED_FORMS @@ -13,6 +15,12 @@ #define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 #endif +#ifndef TEST_SME2 +#define ATTR +#else +#define ATTR __arm_streaming +#endif + // CHECK-LABEL: @test_svst1_u8_x2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.vector.extract.nxv16i8.nxv32i8( [[V:%.*]], i64 0) @@ -27,7 +35,7 @@ // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u8_x2(svcount_t pn, uint8_t *base, svuint8x2_t v) +void test_svst1_u8_x2(svcount_t pn, uint8_t *base, svuint8x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u8_x2,,)(pn, base, v); } @@ -46,7 +54,7 @@ void test_svst1_u8_x2(svcount_t pn, uint8_t *base, svuint8x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u16_x2(svcount_t pn, uint16_t *base, svuint16x2_t v) +void test_svst1_u16_x2(svcount_t pn, uint16_t *base, svuint16x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u16_x2,,)(pn, base, v); } @@ -65,7 +73,7 @@ void test_svst1_u16_x2(svcount_t pn, uint16_t *base, svuint16x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u32_x2(svcount_t pn, uint32_t *base, svuint32x2_t v) +void test_svst1_u32_x2(svcount_t pn, uint32_t *base, svuint32x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u32_x2,,)(pn, base, v); } @@ -84,7 +92,7 @@ void test_svst1_u32_x2(svcount_t pn, uint32_t *base, svuint32x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u64_x2(svcount_t pn, uint64_t *base, svuint64x2_t v) +void test_svst1_u64_x2(svcount_t pn, uint64_t *base, svuint64x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u64_x2,,)(pn, base, v); } @@ -107,7 +115,7 @@ void test_svst1_u64_x2(svcount_t pn, uint64_t *base, svuint64x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u8_x4(svcount_t pn, uint8_t *base, svuint8x4_t v) +void test_svst1_u8_x4(svcount_t pn, uint8_t *base, svuint8x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u8_x4,,)(pn, base, v); } @@ -130,7 +138,7 @@ void test_svst1_u8_x4(svcount_t pn, uint8_t *base, svuint8x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u16_x4(svcount_t pn, uint16_t *base, svuint16x4_t v) +void test_svst1_u16_x4(svcount_t pn, uint16_t *base, svuint16x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u16_x4,,)(pn, base, v); } @@ -153,7 +161,7 @@ void test_svst1_u16_x4(svcount_t pn, uint16_t *base, svuint16x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u32_x4(svcount_t pn, uint32_t *base, svuint32x4_t v) +void test_svst1_u32_x4(svcount_t pn, uint32_t *base, svuint32x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u32_x4,,)(pn, base, v); } @@ -176,7 +184,7 @@ void test_svst1_u32_x4(svcount_t pn, uint32_t *base, svuint32x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_u64_x4(svcount_t pn, uint64_t *base, svuint64x4_t v) +void test_svst1_u64_x4(svcount_t pn, uint64_t *base, svuint64x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_u64_x4,,)(pn, base, v); } @@ -195,7 +203,7 @@ void test_svst1_u64_x4(svcount_t pn, uint64_t *base, svuint64x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s8_x2(svcount_t pn, int8_t *base, svint8x2_t v) +void test_svst1_s8_x2(svcount_t pn, int8_t *base, svint8x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s8_x2,,)(pn, base, v); } @@ -214,7 +222,7 @@ void test_svst1_s8_x2(svcount_t pn, int8_t *base, svint8x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s16_x2(svcount_t pn, int16_t *base, svint16x2_t v) +void test_svst1_s16_x2(svcount_t pn, int16_t *base, svint16x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s16_x2,,)(pn, base, v); } @@ -233,7 +241,7 @@ void test_svst1_s16_x2(svcount_t pn, int16_t *base, svint16x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s32_x2(svcount_t pn, int32_t *base, svint32x2_t v) +void test_svst1_s32_x2(svcount_t pn, int32_t *base, svint32x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s32_x2,,)(pn, base, v); } @@ -252,7 +260,7 @@ void test_svst1_s32_x2(svcount_t pn, int32_t *base, svint32x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s64_x2(svcount_t pn, int64_t *base, svint64x2_t v) +void test_svst1_s64_x2(svcount_t pn, int64_t *base, svint64x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s64_x2,,)(pn, base, v); } @@ -275,7 +283,7 @@ void test_svst1_s64_x2(svcount_t pn, int64_t *base, svint64x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s8_x4(svcount_t pn, int8_t *base, svint8x4_t v) +void test_svst1_s8_x4(svcount_t pn, int8_t *base, svint8x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s8_x4,,)(pn, base, v); } @@ -298,7 +306,7 @@ void test_svst1_s8_x4(svcount_t pn, int8_t *base, svint8x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s16_x4(svcount_t pn, int16_t *base, svint16x4_t v) +void test_svst1_s16_x4(svcount_t pn, int16_t *base, svint16x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s16_x4,,)(pn, base, v); } @@ -321,7 +329,7 @@ void test_svst1_s16_x4(svcount_t pn, int16_t *base, svint16x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s32_x4(svcount_t pn, int32_t *base, svint32x4_t v) +void test_svst1_s32_x4(svcount_t pn, int32_t *base, svint32x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s32_x4,,)(pn, base, v); } @@ -344,7 +352,7 @@ void test_svst1_s32_x4(svcount_t pn, int32_t *base, svint32x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_s64_x4(svcount_t pn, int64_t *base, svint64x4_t v) +void test_svst1_s64_x4(svcount_t pn, int64_t *base, svint64x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_s64_x4,,)(pn, base, v); } @@ -363,7 +371,7 @@ void test_svst1_s64_x4(svcount_t pn, int64_t *base, svint64x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv8f16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_f16_x2(svcount_t pn, float16_t *base, svfloat16x2_t v) +void test_svst1_f16_x2(svcount_t pn, float16_t *base, svfloat16x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_f16_x2,,)(pn, base, v); } @@ -382,7 +390,7 @@ void test_svst1_f16_x2(svcount_t pn, float16_t *base, svfloat16x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv4f32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_f32_x2(svcount_t pn, float32_t *base, svfloat32x2_t v) +void test_svst1_f32_x2(svcount_t pn, float32_t *base, svfloat32x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_f32_x2,,)(pn, base, v); } @@ -401,7 +409,7 @@ void test_svst1_f32_x2(svcount_t pn, float32_t *base, svfloat32x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv2f64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_f64_x2(svcount_t pn, float64_t *base, svfloat64x2_t v) +void test_svst1_f64_x2(svcount_t pn, float64_t *base, svfloat64x2_t v) ATTR { return SVE_ACLE_FUNC(svst1,_f64_x2,,)(pn, base, v); } @@ -424,7 +432,7 @@ void test_svst1_f64_x2(svcount_t pn, float64_t *base, svfloat64x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_f16_x4(svcount_t pn, float16_t *base, svfloat16x4_t v) +void test_svst1_f16_x4(svcount_t pn, float16_t *base, svfloat16x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_f16_x4,,)(pn, base, v); } @@ -447,7 +455,7 @@ void test_svst1_f16_x4(svcount_t pn, float16_t *base, svfloat16x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_f32_x4(svcount_t pn, float32_t *base, svfloat32x4_t v) +void test_svst1_f32_x4(svcount_t pn, float32_t *base, svfloat32x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_f32_x4,,)(pn, base, v); } @@ -470,7 +478,7 @@ void test_svst1_f32_x4(svcount_t pn, float32_t *base, svfloat32x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_f64_x4(svcount_t pn, float64_t *base, svfloat64x4_t v) +void test_svst1_f64_x4(svcount_t pn, float64_t *base, svfloat64x4_t v) ATTR { return SVE_ACLE_FUNC(svst1,_f64_x4,,)(pn, base, v); } @@ -495,7 +503,7 @@ void test_svst1_f64_x4(svcount_t pn, float64_t *base, svfloat64x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u8_x2(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x2_t v) +void test_svst1_vnum_u8_x2(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u8_x2,,)(pn, base, vnum, v); } @@ -516,7 +524,7 @@ void test_svst1_vnum_u8_x2(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x2_ // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u16_x2(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x2_t v) +void test_svst1_vnum_u16_x2(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u16_x2,,)(pn, base, vnum, v); } @@ -537,7 +545,7 @@ void test_svst1_vnum_u16_x2(svcount_t pn, uint16_t *base, int64_t vnum, svuint16 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u32_x2(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x2_t v) +void test_svst1_vnum_u32_x2(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u32_x2,,)(pn, base, vnum, v); } @@ -558,7 +566,7 @@ void test_svst1_vnum_u32_x2(svcount_t pn, uint32_t *base, int64_t vnum, svuint32 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u64_x2(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x2_t v) +void test_svst1_vnum_u64_x2(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u64_x2,,)(pn, base, vnum, v); } @@ -583,7 +591,7 @@ void test_svst1_vnum_u64_x2(svcount_t pn, uint64_t *base, int64_t vnum, svuint64 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u8_x4(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x4_t v) +void test_svst1_vnum_u8_x4(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u8_x4,,)(pn, base, vnum, v); } @@ -608,7 +616,7 @@ void test_svst1_vnum_u8_x4(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x4_ // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u16_x4(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x4_t v) +void test_svst1_vnum_u16_x4(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u16_x4,,)(pn, base, vnum, v); } @@ -633,7 +641,7 @@ void test_svst1_vnum_u16_x4(svcount_t pn, uint16_t *base, int64_t vnum, svuint16 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u32_x4(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x4_t v) +void test_svst1_vnum_u32_x4(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u32_x4,,)(pn, base, vnum, v); } @@ -658,7 +666,7 @@ void test_svst1_vnum_u32_x4(svcount_t pn, uint32_t *base, int64_t vnum, svuint32 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_u64_x4(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x4_t v) +void test_svst1_vnum_u64_x4(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_u64_x4,,)(pn, base, vnum, v); } @@ -679,7 +687,7 @@ void test_svst1_vnum_u64_x4(svcount_t pn, uint64_t *base, int64_t vnum, svuint64 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s8_x2(svcount_t pn, int8_t *base, int64_t vnum, svint8x2_t v) +void test_svst1_vnum_s8_x2(svcount_t pn, int8_t *base, int64_t vnum, svint8x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s8_x2,,)(pn, base, vnum, v); } @@ -700,7 +708,7 @@ void test_svst1_vnum_s8_x2(svcount_t pn, int8_t *base, int64_t vnum, svint8x2_t // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s16_x2(svcount_t pn, int16_t *base, int64_t vnum, svint16x2_t v) +void test_svst1_vnum_s16_x2(svcount_t pn, int16_t *base, int64_t vnum, svint16x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s16_x2,,)(pn, base, vnum, v); } @@ -721,7 +729,7 @@ void test_svst1_vnum_s16_x2(svcount_t pn, int16_t *base, int64_t vnum, svint16x2 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s32_x2(svcount_t pn, int32_t *base, int64_t vnum, svint32x2_t v) +void test_svst1_vnum_s32_x2(svcount_t pn, int32_t *base, int64_t vnum, svint32x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s32_x2,,)(pn, base, vnum, v); } @@ -742,7 +750,7 @@ void test_svst1_vnum_s32_x2(svcount_t pn, int32_t *base, int64_t vnum, svint32x2 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s64_x2(svcount_t pn, int64_t *base, int64_t vnum, svint64x2_t v) +void test_svst1_vnum_s64_x2(svcount_t pn, int64_t *base, int64_t vnum, svint64x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s64_x2,,)(pn, base, vnum, v); } @@ -767,7 +775,7 @@ void test_svst1_vnum_s64_x2(svcount_t pn, int64_t *base, int64_t vnum, svint64x2 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s8_x4(svcount_t pn, int8_t *base, int64_t vnum, svint8x4_t v) +void test_svst1_vnum_s8_x4(svcount_t pn, int8_t *base, int64_t vnum, svint8x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s8_x4,,)(pn, base, vnum, v); } @@ -792,7 +800,7 @@ void test_svst1_vnum_s8_x4(svcount_t pn, int8_t *base, int64_t vnum, svint8x4_t // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s16_x4(svcount_t pn, int16_t *base, int64_t vnum, svint16x4_t v) +void test_svst1_vnum_s16_x4(svcount_t pn, int16_t *base, int64_t vnum, svint16x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s16_x4,,)(pn, base, vnum, v); } @@ -817,7 +825,7 @@ void test_svst1_vnum_s16_x4(svcount_t pn, int16_t *base, int64_t vnum, svint16x4 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s32_x4(svcount_t pn, int32_t *base, int64_t vnum, svint32x4_t v) +void test_svst1_vnum_s32_x4(svcount_t pn, int32_t *base, int64_t vnum, svint32x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s32_x4,,)(pn, base, vnum, v); } @@ -842,7 +850,7 @@ void test_svst1_vnum_s32_x4(svcount_t pn, int32_t *base, int64_t vnum, svint32x4 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_s64_x4(svcount_t pn, int64_t *base, int64_t vnum, svint64x4_t v) +void test_svst1_vnum_s64_x4(svcount_t pn, int64_t *base, int64_t vnum, svint64x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_s64_x4,,)(pn, base, vnum, v); } @@ -865,7 +873,7 @@ void test_svst1_vnum_s64_x4(svcount_t pn, int64_t *base, int64_t vnum, svint64x4 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv8f16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_f16_x2(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x2_t v) +void test_svst1_vnum_f16_x2(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_f16_x2,,)(pn, base, vnum, v); } @@ -888,7 +896,7 @@ void test_svst1_vnum_f16_x2(svcount_t pn, float16_t *base, float64_t vnum, svflo // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv4f32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_f32_x2(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x2_t v) +void test_svst1_vnum_f32_x2(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_f32_x2,,)(pn, base, vnum, v); } @@ -911,7 +919,7 @@ void test_svst1_vnum_f32_x2(svcount_t pn, float32_t *base, float64_t vnum, svflo // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x2.nxv2f64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_f64_x2(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x2_t v) +void test_svst1_vnum_f64_x2(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x2_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_f64_x2,,)(pn, base, vnum, v); } @@ -938,7 +946,7 @@ void test_svst1_vnum_f64_x2(svcount_t pn, float64_t *base, float64_t vnum, svflo // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_f16_x4(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x4_t v) +void test_svst1_vnum_f16_x4(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_f16_x4,,)(pn, base, vnum, v); } @@ -965,7 +973,7 @@ void test_svst1_vnum_f16_x4(svcount_t pn, float16_t *base, float64_t vnum, svflo // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_f32_x4(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x4_t v) +void test_svst1_vnum_f32_x4(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_f32_x4,,)(pn, base, vnum, v); } @@ -992,7 +1000,7 @@ void test_svst1_vnum_f32_x4(svcount_t pn, float32_t *base, float64_t vnum, svflo // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st1.pn.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svst1_vnum_f64_x4(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x4_t v) +void test_svst1_vnum_f64_x4(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x4_t v) ATTR { return SVE_ACLE_FUNC(svst1_vnum,_f64_x4,,)(pn, base, vnum, v); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_stnt1.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_stnt1.c index 9b860fe7180e199e6ea2638829a88e1c6dc4e63f..0d8696a7634a70f909f372448553dc68f20cc8a8 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_stnt1.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_stnt1.c @@ -1,9 +1,12 @@ // 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 +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -DTEST_SME2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + #include #ifdef SVE_OVERLOADED_FORMS @@ -13,6 +16,11 @@ #define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 #endif +#ifndef TEST_SME2 +#define ATTR +#else +#define ATTR __arm_streaming +#endif // CHECK-LABEL: @test_svstnt1_u8_x2( // CHECK-NEXT: entry: @@ -28,7 +36,7 @@ // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u8_x2(svcount_t pn, uint8_t *base, svuint8x2_t v) +void test_svstnt1_u8_x2(svcount_t pn, uint8_t *base, svuint8x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u8_x2,,)(pn, base, v); } @@ -48,7 +56,7 @@ void test_svstnt1_u8_x2(svcount_t pn, uint8_t *base, svuint8x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u16_x2(svcount_t pn, uint16_t *base, svuint16x2_t v) +void test_svstnt1_u16_x2(svcount_t pn, uint16_t *base, svuint16x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u16_x2,,)(pn, base, v); } @@ -68,7 +76,7 @@ void test_svstnt1_u16_x2(svcount_t pn, uint16_t *base, svuint16x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u32_x2(svcount_t pn, uint32_t *base, svuint32x2_t v) +void test_svstnt1_u32_x2(svcount_t pn, uint32_t *base, svuint32x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u32_x2,,)(pn, base, v); } @@ -88,7 +96,7 @@ void test_svstnt1_u32_x2(svcount_t pn, uint32_t *base, svuint32x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u64_x2(svcount_t pn, uint64_t *base, svuint64x2_t v) +void test_svstnt1_u64_x2(svcount_t pn, uint64_t *base, svuint64x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u64_x2,,)(pn, base, v); } @@ -112,7 +120,7 @@ void test_svstnt1_u64_x2(svcount_t pn, uint64_t *base, svuint64x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u8_x4(svcount_t pn, uint8_t *base, svuint8x4_t v) +void test_svstnt1_u8_x4(svcount_t pn, uint8_t *base, svuint8x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u8_x4,,)(pn, base, v); } @@ -136,7 +144,7 @@ void test_svstnt1_u8_x4(svcount_t pn, uint8_t *base, svuint8x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u16_x4(svcount_t pn, uint16_t *base, svuint16x4_t v) +void test_svstnt1_u16_x4(svcount_t pn, uint16_t *base, svuint16x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u16_x4,,)(pn, base, v); } @@ -160,7 +168,7 @@ void test_svstnt1_u16_x4(svcount_t pn, uint16_t *base, svuint16x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u32_x4(svcount_t pn, uint32_t *base, svuint32x4_t v) +void test_svstnt1_u32_x4(svcount_t pn, uint32_t *base, svuint32x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u32_x4,,)(pn, base, v); } @@ -184,7 +192,7 @@ void test_svstnt1_u32_x4(svcount_t pn, uint32_t *base, svuint32x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_u64_x4(svcount_t pn, uint64_t *base, svuint64x4_t v) +void test_svstnt1_u64_x4(svcount_t pn, uint64_t *base, svuint64x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_u64_x4,,)(pn, base, v); } @@ -204,7 +212,7 @@ void test_svstnt1_u64_x4(svcount_t pn, uint64_t *base, svuint64x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s8_x2(svcount_t pn, int8_t *base, svint8x2_t v) +void test_svstnt1_s8_x2(svcount_t pn, int8_t *base, svint8x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s8_x2,,)(pn, base, v); } @@ -224,7 +232,7 @@ void test_svstnt1_s8_x2(svcount_t pn, int8_t *base, svint8x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s16_x2(svcount_t pn, int16_t *base, svint16x2_t v) +void test_svstnt1_s16_x2(svcount_t pn, int16_t *base, svint16x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s16_x2,,)(pn, base, v); } @@ -244,7 +252,7 @@ void test_svstnt1_s16_x2(svcount_t pn, int16_t *base, svint16x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s32_x2(svcount_t pn, int32_t *base, svint32x2_t v) +void test_svstnt1_s32_x2(svcount_t pn, int32_t *base, svint32x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s32_x2,,)(pn, base, v); } @@ -264,7 +272,7 @@ void test_svstnt1_s32_x2(svcount_t pn, int32_t *base, svint32x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s64_x2(svcount_t pn, int64_t *base, svint64x2_t v) +void test_svstnt1_s64_x2(svcount_t pn, int64_t *base, svint64x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s64_x2,,)(pn, base, v); } @@ -288,7 +296,7 @@ void test_svstnt1_s64_x2(svcount_t pn, int64_t *base, svint64x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s8_x4(svcount_t pn, int8_t *base, svint8x4_t v) +void test_svstnt1_s8_x4(svcount_t pn, int8_t *base, svint8x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s8_x4,,)(pn, base, v); } @@ -312,7 +320,7 @@ void test_svstnt1_s8_x4(svcount_t pn, int8_t *base, svint8x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s16_x4(svcount_t pn, int16_t *base, svint16x4_t v) +void test_svstnt1_s16_x4(svcount_t pn, int16_t *base, svint16x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s16_x4,,)(pn, base, v); } @@ -336,7 +344,7 @@ void test_svstnt1_s16_x4(svcount_t pn, int16_t *base, svint16x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s32_x4(svcount_t pn, int32_t *base, svint32x4_t v) +void test_svstnt1_s32_x4(svcount_t pn, int32_t *base, svint32x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s32_x4,,)(pn, base, v); } @@ -360,7 +368,7 @@ void test_svstnt1_s32_x4(svcount_t pn, int32_t *base, svint32x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_s64_x4(svcount_t pn, int64_t *base, svint64x4_t v) +void test_svstnt1_s64_x4(svcount_t pn, int64_t *base, svint64x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_s64_x4,,)(pn, base, v); } @@ -380,7 +388,7 @@ void test_svstnt1_s64_x4(svcount_t pn, int64_t *base, svint64x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv8f16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_f16_x2(svcount_t pn, float16_t *base, svfloat16x2_t v) +void test_svstnt1_f16_x2(svcount_t pn, float16_t *base, svfloat16x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_f16_x2,,)(pn, base, v); } @@ -400,7 +408,7 @@ void test_svstnt1_f16_x2(svcount_t pn, float16_t *base, svfloat16x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv4f32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_f32_x2(svcount_t pn, float32_t *base, svfloat32x2_t v) +void test_svstnt1_f32_x2(svcount_t pn, float32_t *base, svfloat32x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_f32_x2,,)(pn, base, v); } @@ -420,7 +428,7 @@ void test_svstnt1_f32_x2(svcount_t pn, float32_t *base, svfloat32x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv2f64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_f64_x2(svcount_t pn, float64_t *base, svfloat64x2_t v) +void test_svstnt1_f64_x2(svcount_t pn, float64_t *base, svfloat64x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_f64_x2,,)(pn, base, v); } @@ -444,7 +452,7 @@ void test_svstnt1_f64_x2(svcount_t pn, float64_t *base, svfloat64x2_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_f16_x4(svcount_t pn, float16_t *base, svfloat16x4_t v) +void test_svstnt1_f16_x4(svcount_t pn, float16_t *base, svfloat16x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_f16_x4,,)(pn, base, v); } @@ -468,7 +476,7 @@ void test_svstnt1_f16_x4(svcount_t pn, float16_t *base, svfloat16x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_f32_x4(svcount_t pn, float32_t *base, svfloat32x4_t v) +void test_svstnt1_f32_x4(svcount_t pn, float32_t *base, svfloat32x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_f32_x4,,)(pn, base, v); } @@ -492,7 +500,7 @@ void test_svstnt1_f32_x4(svcount_t pn, float32_t *base, svfloat32x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[BASE:%.*]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_f64_x4(svcount_t pn, float64_t *base, svfloat64x4_t v) +void test_svstnt1_f64_x4(svcount_t pn, float64_t *base, svfloat64x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1,_f64_x4,,)(pn, base, v); } @@ -518,7 +526,7 @@ void test_svstnt1_f64_x4(svcount_t pn, float64_t *base, svfloat64x4_t v) // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u8_x2(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x2_t v) +void test_svstnt1_vnum_u8_x2(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u8_x2,,)(pn, base, vnum, v); } @@ -540,7 +548,7 @@ void test_svstnt1_vnum_u8_x2(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u16_x2(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x2_t v) +void test_svstnt1_vnum_u16_x2(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u16_x2,,)(pn, base, vnum, v); } @@ -562,7 +570,7 @@ void test_svstnt1_vnum_u16_x2(svcount_t pn, uint16_t *base, int64_t vnum, svuint // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u32_x2(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x2_t v) +void test_svstnt1_vnum_u32_x2(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u32_x2,,)(pn, base, vnum, v); } @@ -584,7 +592,7 @@ void test_svstnt1_vnum_u32_x2(svcount_t pn, uint32_t *base, int64_t vnum, svuint // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u64_x2(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x2_t v) +void test_svstnt1_vnum_u64_x2(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u64_x2,,)(pn, base, vnum, v); } @@ -610,7 +618,7 @@ void test_svstnt1_vnum_u64_x2(svcount_t pn, uint64_t *base, int64_t vnum, svuint // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u8_x4(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x4_t v) +void test_svstnt1_vnum_u8_x4(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u8_x4,,)(pn, base, vnum, v); } @@ -636,7 +644,7 @@ void test_svstnt1_vnum_u8_x4(svcount_t pn, uint8_t *base, int64_t vnum, svuint8x // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u16_x4(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x4_t v) +void test_svstnt1_vnum_u16_x4(svcount_t pn, uint16_t *base, int64_t vnum, svuint16x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u16_x4,,)(pn, base, vnum, v); } @@ -662,7 +670,7 @@ void test_svstnt1_vnum_u16_x4(svcount_t pn, uint16_t *base, int64_t vnum, svuint // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u32_x4(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x4_t v) +void test_svstnt1_vnum_u32_x4(svcount_t pn, uint32_t *base, int64_t vnum, svuint32x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u32_x4,,)(pn, base, vnum, v); } @@ -688,7 +696,7 @@ void test_svstnt1_vnum_u32_x4(svcount_t pn, uint32_t *base, int64_t vnum, svuint // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_u64_x4(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x4_t v) +void test_svstnt1_vnum_u64_x4(svcount_t pn, uint64_t *base, int64_t vnum, svuint64x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_u64_x4,,)(pn, base, vnum, v); } @@ -710,7 +718,7 @@ void test_svstnt1_vnum_u64_x4(svcount_t pn, uint64_t *base, int64_t vnum, svuint // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv16i8( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s8_x2(svcount_t pn, int8_t *base, int64_t vnum, svint8x2_t v) +void test_svstnt1_vnum_s8_x2(svcount_t pn, int8_t *base, int64_t vnum, svint8x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s8_x2,,)(pn, base, vnum, v); } @@ -732,7 +740,7 @@ void test_svstnt1_vnum_s8_x2(svcount_t pn, int8_t *base, int64_t vnum, svint8x2_ // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv8i16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s16_x2(svcount_t pn, int16_t *base, int64_t vnum, svint16x2_t v) +void test_svstnt1_vnum_s16_x2(svcount_t pn, int16_t *base, int64_t vnum, svint16x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s16_x2,,)(pn, base, vnum, v); } @@ -754,7 +762,7 @@ void test_svstnt1_vnum_s16_x2(svcount_t pn, int16_t *base, int64_t vnum, svint16 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv4i32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s32_x2(svcount_t pn, int32_t *base, int64_t vnum, svint32x2_t v) +void test_svstnt1_vnum_s32_x2(svcount_t pn, int32_t *base, int64_t vnum, svint32x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s32_x2,,)(pn, base, vnum, v); } @@ -776,7 +784,7 @@ void test_svstnt1_vnum_s32_x2(svcount_t pn, int32_t *base, int64_t vnum, svint32 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv2i64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s64_x2(svcount_t pn, int64_t *base, int64_t vnum, svint64x2_t v) +void test_svstnt1_vnum_s64_x2(svcount_t pn, int64_t *base, int64_t vnum, svint64x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s64_x2,,)(pn, base, vnum, v); } @@ -802,7 +810,7 @@ void test_svstnt1_vnum_s64_x2(svcount_t pn, int64_t *base, int64_t vnum, svint64 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv16i8( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s8_x4(svcount_t pn, int8_t *base, int64_t vnum, svint8x4_t v) +void test_svstnt1_vnum_s8_x4(svcount_t pn, int8_t *base, int64_t vnum, svint8x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s8_x4,,)(pn, base, vnum, v); } @@ -828,7 +836,7 @@ void test_svstnt1_vnum_s8_x4(svcount_t pn, int8_t *base, int64_t vnum, svint8x4_ // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv8i16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s16_x4(svcount_t pn, int16_t *base, int64_t vnum, svint16x4_t v) +void test_svstnt1_vnum_s16_x4(svcount_t pn, int16_t *base, int64_t vnum, svint16x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s16_x4,,)(pn, base, vnum, v); } @@ -854,7 +862,7 @@ void test_svstnt1_vnum_s16_x4(svcount_t pn, int16_t *base, int64_t vnum, svint16 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv4i32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s32_x4(svcount_t pn, int32_t *base, int64_t vnum, svint32x4_t v) +void test_svstnt1_vnum_s32_x4(svcount_t pn, int32_t *base, int64_t vnum, svint32x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s32_x4,,)(pn, base, vnum, v); } @@ -880,7 +888,7 @@ void test_svstnt1_vnum_s32_x4(svcount_t pn, int32_t *base, int64_t vnum, svint32 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv2i64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_s64_x4(svcount_t pn, int64_t *base, int64_t vnum, svint64x4_t v) +void test_svstnt1_vnum_s64_x4(svcount_t pn, int64_t *base, int64_t vnum, svint64x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_s64_x4,,)(pn, base, vnum, v); } @@ -904,7 +912,7 @@ void test_svstnt1_vnum_s64_x4(svcount_t pn, int64_t *base, int64_t vnum, svint64 // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv8f16( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_f16_x2(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x2_t v) +void test_svstnt1_vnum_f16_x2(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_f16_x2,,)(pn, base, vnum, v); } @@ -928,7 +936,7 @@ void test_svstnt1_vnum_f16_x2(svcount_t pn, float16_t *base, float64_t vnum, svf // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv4f32( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_f32_x2(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x2_t v) +void test_svstnt1_vnum_f32_x2(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_f32_x2,,)(pn, base, vnum, v); } @@ -952,7 +960,7 @@ void test_svstnt1_vnum_f32_x2(svcount_t pn, float32_t *base, float64_t vnum, svf // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x2.nxv2f64( [[TMP0]], [[TMP1]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP2]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_f64_x2(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x2_t v) +void test_svstnt1_vnum_f64_x2(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x2_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_f64_x2,,)(pn, base, vnum, v); } @@ -980,7 +988,7 @@ void test_svstnt1_vnum_f64_x2(svcount_t pn, float64_t *base, float64_t vnum, svf // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv8f16( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_f16_x4(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x4_t v) +void test_svstnt1_vnum_f16_x4(svcount_t pn, float16_t *base, float64_t vnum, svfloat16x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_f16_x4,,)(pn, base, vnum, v); } @@ -1008,7 +1016,7 @@ void test_svstnt1_vnum_f16_x4(svcount_t pn, float16_t *base, float64_t vnum, svf // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv4f32( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_f32_x4(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x4_t v) +void test_svstnt1_vnum_f32_x4(svcount_t pn, float32_t *base, float64_t vnum, svfloat32x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_f32_x4,,)(pn, base, vnum, v); } @@ -1036,7 +1044,7 @@ void test_svstnt1_vnum_f32_x4(svcount_t pn, float32_t *base, float64_t vnum, svf // CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.stnt1.pn.x4.nxv2f64( [[TMP0]], [[TMP1]], [[TMP2]], [[TMP3]], target("aarch64.svcount") [[PN:%.*]], ptr [[TMP4]]) // CPP-CHECK-NEXT: ret void // -void test_svstnt1_vnum_f64_x4(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x4_t v) +void test_svstnt1_vnum_f64_x4(svcount_t pn, float64_t *base, float64_t vnum, svfloat64x4_t v) ATTR { return SVE_ACLE_FUNC(svstnt1_vnum,_f64_x4,,)(pn, base, vnum, v); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_pn.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_pn.c index 3dbb38582b676c3a424beea726b0f1c4c661cafd..143a43b4a9219892e3f7e88efb019ad26fb96e60 100644 --- a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_pn.c +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_pn.c @@ -1,12 +1,21 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s // REQUIRES: aarch64-registered-target #include +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1, A2_UNUSED) A1 +#else +#define SVE_ACLE_FUNC(A1, A2) A1##A2 +#endif + // WHILEGE @@ -22,7 +31,7 @@ // svcount_t test_svwhilege_c8_vl2(int64_t op1, int64_t op2) { - return svwhilege_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c8,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilege_c8_vl4( @@ -37,7 +46,7 @@ svcount_t test_svwhilege_c8_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c8_vl4(int64_t op1, int64_t op2) { - return svwhilege_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c8,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilege_c16_vl2( @@ -52,7 +61,7 @@ svcount_t test_svwhilege_c8_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c16_vl2(int64_t op1, int64_t op2) { - return svwhilege_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c16,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilege_c16_vl4( @@ -67,7 +76,7 @@ svcount_t test_svwhilege_c16_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c16_vl4(int64_t op1, int64_t op2) { - return svwhilege_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c16,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilege_c32_vl2( @@ -82,7 +91,7 @@ svcount_t test_svwhilege_c16_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c32_vl2(int64_t op1, int64_t op2) { - return svwhilege_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c32,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilege_c32_vl4( @@ -97,7 +106,7 @@ svcount_t test_svwhilege_c32_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c32_vl4(int64_t op1, int64_t op2) { - return svwhilege_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c32,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilege_c64_vl2( @@ -112,7 +121,7 @@ svcount_t test_svwhilege_c32_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c64_vl2(int64_t op1, int64_t op2) { - return svwhilege_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c64,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilege_c64_vl4( @@ -127,7 +136,7 @@ svcount_t test_svwhilege_c64_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilege_c64_vl4(int64_t op1, int64_t op2) { - return svwhilege_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c64,_s64)(op1, op2, 4); } // WHILEGT @@ -145,7 +154,7 @@ svcount_t test_svwhilege_c64_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c8_vl2(int64_t op1, int64_t op2) { - return svwhilegt_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c8,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilegt_c8_vl4( @@ -160,7 +169,7 @@ svcount_t test_svwhilegt_c8_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c8_vl4(int64_t op1, int64_t op2) { - return svwhilegt_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c8,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilegt_c16_vl2( @@ -175,7 +184,7 @@ svcount_t test_svwhilegt_c8_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c16_vl2(int64_t op1, int64_t op2) { - return svwhilegt_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c16,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilegt_c16_vl4( @@ -190,7 +199,7 @@ svcount_t test_svwhilegt_c16_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c16_vl4(int64_t op1, int64_t op2) { - return svwhilegt_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c16,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilegt_c32_vl2( @@ -205,7 +214,7 @@ svcount_t test_svwhilegt_c16_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c32_vl2(int64_t op1, int64_t op2) { - return svwhilegt_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c32,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilegt_c32_vl4( @@ -220,7 +229,7 @@ svcount_t test_svwhilegt_c32_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c32_vl4(int64_t op1, int64_t op2) { - return svwhilegt_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c32,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilegt_c64_vl2( @@ -235,7 +244,7 @@ svcount_t test_svwhilegt_c32_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c64_vl2(int64_t op1, int64_t op2) { - return svwhilegt_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c64,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilegt_c64_vl4( @@ -250,7 +259,7 @@ svcount_t test_svwhilegt_c64_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilegt_c64_vl4(int64_t op1, int64_t op2) { - return svwhilegt_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c64,_s64)(op1, op2, 4); } @@ -268,7 +277,7 @@ svcount_t test_svwhilegt_c64_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilehi_c8_vl2(uint64_t op1, uint64_t op2) { - return svwhilehi_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c8,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehi_c8_vl4( @@ -283,7 +292,7 @@ svcount_t test_svwhilehi_c8_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c8_vl4(uint64_t op1, uint64_t op2) { - return svwhilehi_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c8,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilehi_c16_vl2( @@ -298,7 +307,7 @@ svcount_t test_svwhilehi_c8_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c16_vl2(uint64_t op1, uint64_t op2) { - return svwhilehi_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c16,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehi_c16_vl4( @@ -313,7 +322,7 @@ svcount_t test_svwhilehi_c16_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c16_vl4(uint64_t op1, uint64_t op2) { - return svwhilehi_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c16,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilehi_c32_vl2( @@ -328,7 +337,7 @@ svcount_t test_svwhilehi_c16_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c32_vl2(uint64_t op1, uint64_t op2) { - return svwhilehi_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c32,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehi_c32_vl4( @@ -343,7 +352,7 @@ svcount_t test_svwhilehi_c32_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c32_vl4(uint64_t op1, uint64_t op2) { - return svwhilehi_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c32,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilehi_c64_vl2( @@ -358,7 +367,7 @@ svcount_t test_svwhilehi_c32_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c64_vl2(uint64_t op1, uint64_t op2) { - return svwhilehi_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilegt_c64,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehi_c64_vl4( @@ -373,7 +382,7 @@ svcount_t test_svwhilehi_c64_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehi_c64_vl4(uint64_t op1, uint64_t op2) { - return svwhilehi_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilegt_c64,_u64)(op1, op2, 4); } @@ -391,7 +400,7 @@ svcount_t test_svwhilehi_c64_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c8_vl2(uint64_t op1, uint64_t op2) { - return svwhilehs_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c8,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehs_c8_vl4( @@ -406,7 +415,7 @@ svcount_t test_svwhilehs_c8_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c8_vl4(uint64_t op1, uint64_t op2) { - return svwhilehs_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c8,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilehs_c16_vl2( @@ -421,7 +430,7 @@ svcount_t test_svwhilehs_c8_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c16_vl2(uint64_t op1, uint64_t op2) { - return svwhilehs_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c16,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehs_c16_vl4( @@ -436,7 +445,7 @@ svcount_t test_svwhilehs_c16_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c16_vl4(uint64_t op1, uint64_t op2) { - return svwhilehs_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c16,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilehs_c32_vl2( @@ -451,7 +460,7 @@ svcount_t test_svwhilehs_c16_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c32_vl2(uint64_t op1, uint64_t op2) { - return svwhilehs_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c32,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehs_c32_vl4( @@ -466,7 +475,7 @@ svcount_t test_svwhilehs_c32_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c32_vl4(uint64_t op1, uint64_t op2) { - return svwhilehs_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c32,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilehs_c64_vl2( @@ -481,7 +490,7 @@ svcount_t test_svwhilehs_c32_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c64_vl2(uint64_t op1, uint64_t op2) { - return svwhilehs_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilege_c64,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilehs_c64_vl4( @@ -496,7 +505,7 @@ svcount_t test_svwhilehs_c64_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilehs_c64_vl4(uint64_t op1, uint64_t op2) { - return svwhilehs_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilege_c64,_u64)(op1, op2, 4); } @@ -514,7 +523,7 @@ svcount_t test_svwhilehs_c64_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilele_c8_vl2(int64_t op1, int64_t op2) { - return svwhilele_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c8,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilele_c8_vl4( @@ -529,7 +538,7 @@ svcount_t test_svwhilele_c8_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c8_vl4(int64_t op1, int64_t op2) { - return svwhilele_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c8,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilele_c16_vl2( @@ -544,7 +553,7 @@ svcount_t test_svwhilele_c8_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c16_vl2(int64_t op1, int64_t op2) { - return svwhilele_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c16,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilele_c16_vl4( @@ -559,7 +568,7 @@ svcount_t test_svwhilele_c16_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c16_vl4(int64_t op1, int64_t op2) { - return svwhilele_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c16,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilele_c32_vl2( @@ -574,7 +583,7 @@ svcount_t test_svwhilele_c16_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c32_vl2(int64_t op1, int64_t op2) { - return svwhilele_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c32,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilele_c32_vl4( @@ -589,7 +598,7 @@ svcount_t test_svwhilele_c32_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c32_vl4(int64_t op1, int64_t op2) { - return svwhilele_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c32,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilele_c64_vl2( @@ -604,7 +613,7 @@ svcount_t test_svwhilele_c32_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c64_vl2(int64_t op1, int64_t op2) { - return svwhilele_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c64,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilele_c64_vl4( @@ -619,7 +628,7 @@ svcount_t test_svwhilele_c64_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilele_c64_vl4(int64_t op1, int64_t op2) { - return svwhilele_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c64,_s64)(op1, op2, 4); } @@ -637,7 +646,7 @@ svcount_t test_svwhilele_c64_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilelo_c8_vl2(uint64_t op1, uint64_t op2) { - return svwhilelo_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c8,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelo_c8_vl4( @@ -652,7 +661,7 @@ svcount_t test_svwhilelo_c8_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c8_vl4(uint64_t op1, uint64_t op2) { - return svwhilelo_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c8,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilelo_c16_vl2( @@ -667,7 +676,7 @@ svcount_t test_svwhilelo_c8_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c16_vl2(uint64_t op1, uint64_t op2) { - return svwhilelo_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c16,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelo_c16_vl4( @@ -682,7 +691,7 @@ svcount_t test_svwhilelo_c16_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c16_vl4(uint64_t op1, uint64_t op2) { - return svwhilelo_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c16,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilelo_c32_vl2( @@ -697,7 +706,7 @@ svcount_t test_svwhilelo_c16_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c32_vl2(uint64_t op1, uint64_t op2) { - return svwhilelo_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c32,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelo_c32_vl4( @@ -712,7 +721,7 @@ svcount_t test_svwhilelo_c32_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c32_vl4(uint64_t op1, uint64_t op2) { - return svwhilelo_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c32,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilelo_c64_vl2( @@ -727,7 +736,7 @@ svcount_t test_svwhilelo_c32_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c64_vl2(uint64_t op1, uint64_t op2) { - return svwhilelo_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c64,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelo_c64_vl4( @@ -742,7 +751,7 @@ svcount_t test_svwhilelo_c64_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelo_c64_vl4(uint64_t op1, uint64_t op2) { - return svwhilelo_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c64,_u64)(op1, op2, 4); } @@ -760,7 +769,7 @@ svcount_t test_svwhilelo_c64_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c8_vl2(uint64_t op1, uint64_t op2) { - return svwhilels_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c8,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilels_c8_vl4( @@ -775,7 +784,7 @@ svcount_t test_svwhilels_c8_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c8_vl4(uint64_t op1, uint64_t op2) { - return svwhilels_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c8,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilels_c16_vl2( @@ -790,7 +799,7 @@ svcount_t test_svwhilels_c8_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c16_vl2(uint64_t op1, uint64_t op2) { - return svwhilels_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c16,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilels_c16_vl4( @@ -805,7 +814,7 @@ svcount_t test_svwhilels_c16_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c16_vl4(uint64_t op1, uint64_t op2) { - return svwhilels_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c16,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilels_c32_vl2( @@ -820,7 +829,7 @@ svcount_t test_svwhilels_c16_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c32_vl2(uint64_t op1, uint64_t op2) { - return svwhilels_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c32,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilels_c32_vl4( @@ -835,7 +844,7 @@ svcount_t test_svwhilels_c32_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c32_vl4(uint64_t op1, uint64_t op2) { - return svwhilels_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c32,_u64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilels_c64_vl2( @@ -850,7 +859,7 @@ svcount_t test_svwhilels_c32_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c64_vl2(uint64_t op1, uint64_t op2) { - return svwhilels_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilele_c64,_u64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilels_c64_vl4( @@ -865,7 +874,7 @@ svcount_t test_svwhilels_c64_vl2(uint64_t op1, uint64_t op2) // svcount_t test_svwhilels_c64_vl4(uint64_t op1, uint64_t op2) { - return svwhilels_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilele_c64,_u64)(op1, op2, 4); } @@ -883,7 +892,7 @@ svcount_t test_svwhilels_c64_vl4(uint64_t op1, uint64_t op2) // svcount_t test_svwhilelt_c8_vl2(int64_t op1, int64_t op2) { - return svwhilelt_c8(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c8,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelt_c8_vl4( @@ -898,7 +907,7 @@ svcount_t test_svwhilelt_c8_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c8_vl4(int64_t op1, int64_t op2) { - return svwhilelt_c8(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c8,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilelt_c16_vl2( @@ -913,7 +922,7 @@ svcount_t test_svwhilelt_c8_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c16_vl2(int64_t op1, int64_t op2) { - return svwhilelt_c16(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c16,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelt_c16_vl4( @@ -928,7 +937,7 @@ svcount_t test_svwhilelt_c16_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c16_vl4(int64_t op1, int64_t op2) { - return svwhilelt_c16(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c16,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilelt_c32_vl2( @@ -943,7 +952,7 @@ svcount_t test_svwhilelt_c16_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c32_vl2(int64_t op1, int64_t op2) { - return svwhilelt_c32(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c32,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelt_c32_vl4( @@ -958,7 +967,7 @@ svcount_t test_svwhilelt_c32_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c32_vl4(int64_t op1, int64_t op2) { - return svwhilelt_c32(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c32,_s64)(op1, op2, 4); } // CHECK-LABEL: @test_svwhilelt_c64_vl2( @@ -973,7 +982,7 @@ svcount_t test_svwhilelt_c32_vl4(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c64_vl2(int64_t op1, int64_t op2) { - return svwhilelt_c64(op1, op2, 2); + return SVE_ACLE_FUNC(svwhilelt_c64,_s64)(op1, op2, 2); } // CHECK-LABEL: @test_svwhilelt_c64_vl4( @@ -988,5 +997,5 @@ svcount_t test_svwhilelt_c64_vl2(int64_t op1, int64_t op2) // svcount_t test_svwhilelt_c64_vl4(int64_t op1, int64_t op2) { - return svwhilelt_c64(op1, op2, 4); + return SVE_ACLE_FUNC(svwhilelt_c64,_s64)(op1, op2, 4); } diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_x2.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_x2.c new file mode 100644 index 0000000000000000000000000000000000000000..acead9be3f01d2a5326cd09e8ff7706e038845ac --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_while_x2.c @@ -0,0 +1,879 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -S -disable-O0-optnone -Werror -o /dev/null %s +#include + +#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 + +// CHECK-LABEL: define dso_local @test_svwhilege_b8_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilege_b8_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilege_b8_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b8,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b8_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilege_b8_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilege_b8_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b8,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b16_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilege_b16_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilege_b16_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b16,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b16_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilege_b16_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilege_b16_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b16,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b32_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilege_b32_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilege_b32_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b32,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b32_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilege_b32_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilege_b32_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b32,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b64_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilege_b64_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilege.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilege_b64_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b64,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilege_b64_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilege_b64_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehs.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilege_b64_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilege_b64,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b8_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilegt_b8_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilegt_b8_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b8,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b8_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilegt_b8_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilegt_b8_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b8,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b16_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilegt_b16_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilegt_b16_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b16,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b16_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilegt_b16_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilegt_b16_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b16,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b32_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilegt_b32_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilegt_b32_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b32,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b32_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilegt_b32_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilegt_b32_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b32,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b64_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilegt_b64_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilegt.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilegt_b64_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b64,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilegt_b64_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilegt_b64_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilehi.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilegt_b64_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilegt_b64,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b8_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilele_b8_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilele_b8_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b8,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b8_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilele_b8_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilele_b8_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b8,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b16_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilele_b16_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilele_b16_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b16,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b16_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilele_b16_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilele_b16_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b16,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b32_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilele_b32_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilele_b32_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b32,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b32_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilele_b32_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilele_b32_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b32,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b64_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilele_b64_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilele.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilele_b64_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b64,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilele_b64_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilele_b64_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilels.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilele_b64_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilele_b64,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b8_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilelt_b8_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilelt_b8_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b8,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b8_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CHECK-NEXT: ret [[TMP4]] +// +// CPP-CHECK-LABEL: define dso_local @_Z21test_svwhilelt_b8_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv16i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP1]], i64 0) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP2]], [[TMP3]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP4]] +// +svboolx2_t test_svwhilelt_b8_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b8,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b16_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilelt_b16_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilelt_b16_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b16,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b16_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilelt_b16_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv8i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilelt_b16_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b16,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b32_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilelt_b32_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilelt_b32_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b32,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b32_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilelt_b32_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv4i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv4i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilelt_b32_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b32,_u64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b64_s64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilelt_b64_s64ll( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelt.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilelt_b64_s64(int64_t op1, int64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b64,_s64,_x2)(op1, op2); +} + +// CHECK-LABEL: define dso_local @test_svwhilelt_b64_u64( +// CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CHECK-NEXT: ret [[TMP6]] +// +// CPP-CHECK-LABEL: define dso_local @_Z22test_svwhilelt_b64_u64mm( +// CPP-CHECK-SAME: i64 noundef [[OP1:%.*]], i64 noundef [[OP2:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.whilelo.x2.nxv2i1(i64 [[OP1]], i64 [[OP2]]) +// CPP-CHECK-NEXT: [[TMP1:%.*]] = extractvalue { , } [[TMP0]], 0 +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP1]]) +// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( poison, [[TMP2]], i64 0) +// CPP-CHECK-NEXT: [[TMP4:%.*]] = extractvalue { , } [[TMP0]], 1 +// CPP-CHECK-NEXT: [[TMP5:%.*]] = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( [[TMP4]]) +// CPP-CHECK-NEXT: [[TMP6:%.*]] = tail call @llvm.vector.insert.nxv32i1.nxv16i1( [[TMP3]], [[TMP5]], i64 16) +// CPP-CHECK-NEXT: ret [[TMP6]] +// +svboolx2_t test_svwhilelt_b64_u64(uint64_t op1, uint64_t op2) { + return SVE_ACLE_FUNC(svwhilelt_b64,_u64,_x2)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c index 42751ccd4898ced0a7271d8b7143b472d0ef2d5b..e8798c1b8d9194819899ac8cda1228d86923f694 100644 --- a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c +++ b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c @@ -150,7 +150,7 @@ float16x8_t test_vfmaq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { } // COMMON-LABEL: test_vfma_n_f16 -// COMMONIR: [[TMP0:%.*]] = insertelement <4 x half> undef, half %c, i32 0 +// COMMONIR: [[TMP0:%.*]] = insertelement <4 x half> poison, half %c, i32 0 // COMMONIR: [[TMP1:%.*]] = insertelement <4 x half> [[TMP0]], half %c, i32 1 // COMMONIR: [[TMP2:%.*]] = insertelement <4 x half> [[TMP1]], half %c, i32 2 // COMMONIR: [[TMP3:%.*]] = insertelement <4 x half> [[TMP2]], half %c, i32 3 @@ -163,7 +163,7 @@ float16x4_t test_vfma_n_f16(float16x4_t a, float16x4_t b, float16_t c) { } // COMMON-LABEL: test_vfmaq_n_f16 -// COMMONIR: [[TMP0:%.*]] = insertelement <8 x half> undef, half %c, i32 0 +// COMMONIR: [[TMP0:%.*]] = insertelement <8 x half> poison, half %c, i32 0 // COMMONIR: [[TMP1:%.*]] = insertelement <8 x half> [[TMP0]], half %c, i32 1 // COMMONIR: [[TMP2:%.*]] = insertelement <8 x half> [[TMP1]], half %c, i32 2 // COMMONIR: [[TMP3:%.*]] = insertelement <8 x half> [[TMP2]], half %c, i32 3 @@ -271,7 +271,7 @@ float16x8_t test_vfmsq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { // COMMON-LABEL: test_vfms_n_f16 // COMMONIR: [[SUB:%.*]] = fneg <4 x half> %b -// COMMONIR: [[TMP0:%.*]] = insertelement <4 x half> undef, half %c, i32 0 +// COMMONIR: [[TMP0:%.*]] = insertelement <4 x half> poison, half %c, i32 0 // COMMONIR: [[TMP1:%.*]] = insertelement <4 x half> [[TMP0]], half %c, i32 1 // COMMONIR: [[TMP2:%.*]] = insertelement <4 x half> [[TMP1]], half %c, i32 2 // COMMONIR: [[TMP3:%.*]] = insertelement <4 x half> [[TMP2]], half %c, i32 3 @@ -285,7 +285,7 @@ float16x4_t test_vfms_n_f16(float16x4_t a, float16x4_t b, float16_t c) { // COMMON-LABEL: test_vfmsq_n_f16 // COMMONIR: [[SUB:%.*]] = fneg <8 x half> %b -// COMMONIR: [[TMP0:%.*]] = insertelement <8 x half> undef, half %c, i32 0 +// COMMONIR: [[TMP0:%.*]] = insertelement <8 x half> poison, half %c, i32 0 // COMMONIR: [[TMP1:%.*]] = insertelement <8 x half> [[TMP0]], half %c, i32 1 // COMMONIR: [[TMP2:%.*]] = insertelement <8 x half> [[TMP1]], half %c, i32 2 // COMMONIR: [[TMP3:%.*]] = insertelement <8 x half> [[TMP2]], half %c, i32 3 diff --git a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c index 2b7f7679b5f1416cb134d924ec8135ae02d04e6d..4163e6e0918f1945fdcdc837de128abda3fde822 100644 --- a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c +++ b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c @@ -20,7 +20,7 @@ float16x4_t test_vabs_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vabsq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VABS1_I:%.*]] = call <8 x half> @llvm.fabs.v8f16(<8 x half> [[A]]) @@ -43,7 +43,7 @@ uint16x4_t test_vceqz_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vceqzq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq <8 x half> [[A]], zeroinitializer @@ -67,7 +67,7 @@ uint16x4_t test_vcgez_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcgezq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = fcmp oge <8 x half> [[A]], zeroinitializer @@ -91,7 +91,7 @@ uint16x4_t test_vcgtz_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcgtzq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt <8 x half> [[A]], zeroinitializer @@ -115,7 +115,7 @@ uint16x4_t test_vclez_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vclezq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = fcmp ole <8 x half> [[A]], zeroinitializer @@ -139,7 +139,7 @@ uint16x4_t test_vcltz_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcltzq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <8 x half> [[A]], zeroinitializer @@ -162,7 +162,7 @@ float16x4_t test_vcvt_f16_s16 (int16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_f16_s16 -// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVT_I:%.*]] = sitofp <8 x i16> [[A]] to <8 x half> @@ -184,7 +184,7 @@ float16x4_t test_vcvt_f16_u16 (uint16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_f16_u16 -// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVT_I:%.*]] = uitofp <8 x i16> [[A]] to <8 x half> @@ -206,7 +206,7 @@ int16x4_t test_vcvt_s16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_s16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTZ1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtzs.v8i16.v8f16(<8 x half> [[A]]) @@ -228,7 +228,7 @@ uint16x4_t test_vcvt_u16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_u16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTZ1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtzu.v8i16.v8f16(<8 x half> [[A]]) @@ -261,7 +261,7 @@ uint16x4_t test_vcvta_u16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtaq_s16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTA1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtas.v8i16.v8f16(<8 x half> [[A]]) @@ -283,7 +283,7 @@ int16x4_t test_vcvtm_s16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtmq_s16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTM1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtms.v8i16.v8f16(<8 x half> [[A]]) @@ -305,7 +305,7 @@ uint16x4_t test_vcvtm_u16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtmq_u16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTM1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtmu.v8i16.v8f16(<8 x half> [[A]]) @@ -327,7 +327,7 @@ int16x4_t test_vcvtn_s16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtnq_s16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTN1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtns.v8i16.v8f16(<8 x half> [[A]]) @@ -349,7 +349,7 @@ uint16x4_t test_vcvtn_u16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtnq_u16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTN1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtnu.v8i16.v8f16(<8 x half> [[A]]) @@ -371,7 +371,7 @@ int16x4_t test_vcvtp_s16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtpq_s16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTP1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtps.v8i16.v8f16(<8 x half> [[A]]) @@ -393,7 +393,7 @@ uint16x4_t test_vcvtp_u16_f16 (float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtpq_u16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVTP1_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.fcvtpu.v8i16.v8f16(<8 x half> [[A]]) @@ -415,7 +415,7 @@ float16x4_t test_vneg_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vnegq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <8 x half> [[A]] // CHECK-NEXT: ret <8 x half> [[FNEG_I]] @@ -436,7 +436,7 @@ float16x4_t test_vrecpe_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrecpeq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRECPEQ_V1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.frecpe.v8f16(<8 x half> [[A]]) @@ -458,7 +458,7 @@ float16x4_t test_vrnd_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDZ1_I:%.*]] = call <8 x half> @llvm.trunc.v8f16(<8 x half> [[A]]) @@ -480,7 +480,7 @@ float16x4_t test_vrnda_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndaq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDA1_I:%.*]] = call <8 x half> @llvm.round.v8f16(<8 x half> [[A]]) @@ -502,7 +502,7 @@ float16x4_t test_vrndi_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndiq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDIQ_V1_I:%.*]] = call <8 x half> @llvm.nearbyint.v8f16(<8 x half> [[A]]) @@ -524,7 +524,7 @@ float16x4_t test_vrndm_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndmq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDM1_I:%.*]] = call <8 x half> @llvm.floor.v8f16(<8 x half> [[A]]) @@ -546,7 +546,7 @@ float16x4_t test_vrndn_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndnq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDN1_I:%.*]] = call <8 x half> @llvm.roundeven.v8f16(<8 x half> [[A]]) @@ -568,7 +568,7 @@ float16x4_t test_vrndp_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndpq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDP1_I:%.*]] = call <8 x half> @llvm.ceil.v8f16(<8 x half> [[A]]) @@ -590,7 +590,7 @@ float16x4_t test_vrndx_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrndxq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRNDX1_I:%.*]] = call <8 x half> @llvm.rint.v8f16(<8 x half> [[A]]) @@ -612,7 +612,7 @@ float16x4_t test_vrsqrte_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrsqrteq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VRSQRTEQ_V1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.frsqrte.v8f16(<8 x half> [[A]]) @@ -634,7 +634,7 @@ float16x4_t test_vsqrt_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vsqrtq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VSQRT_I:%.*]] = call <8 x half> @llvm.sqrt.v8f16(<8 x half> [[A]]) @@ -655,7 +655,7 @@ float16x4_t test_vadd_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vaddq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[ADD_I:%.*]] = fadd <8 x half> [[A]], [[B]] // CHECK-NEXT: ret <8 x half> [[ADD_I]] @@ -677,7 +677,7 @@ float16x4_t test_vabd_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vabdq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -701,7 +701,7 @@ uint16x4_t test_vcage_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcageq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -725,7 +725,7 @@ uint16x4_t test_vcagt_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcagtq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -749,7 +749,7 @@ uint16x4_t test_vcale_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcaleq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -773,7 +773,7 @@ uint16x4_t test_vcalt_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcaltq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -796,7 +796,7 @@ uint16x4_t test_vceq_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vceqq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CMP_I:%.*]] = fcmp oeq <8 x half> [[A]], [[B]] // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> @@ -818,7 +818,7 @@ uint16x4_t test_vcge_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcgeq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CMP_I:%.*]] = fcmp oge <8 x half> [[A]], [[B]] // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> @@ -840,7 +840,7 @@ uint16x4_t test_vcgt_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcgtq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CMP_I:%.*]] = fcmp ogt <8 x half> [[A]], [[B]] // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> @@ -862,7 +862,7 @@ uint16x4_t test_vcle_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcleq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CMP_I:%.*]] = fcmp ole <8 x half> [[A]], [[B]] // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> @@ -884,7 +884,7 @@ uint16x4_t test_vclt_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vcltq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CMP_I:%.*]] = fcmp olt <8 x half> [[A]], [[B]] // CHECK-NEXT: [[SEXT_I:%.*]] = sext <8 x i1> [[CMP_I]] to <8 x i16> @@ -907,7 +907,7 @@ float16x4_t test_vcvt_n_f16_s16(int16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_f16_s16 -// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16> @@ -931,7 +931,7 @@ float16x4_t test_vcvt_n_f16_u16(uint16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_f16_u16 -// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16> @@ -955,7 +955,7 @@ int16x4_t test_vcvt_n_s16_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_s16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -979,7 +979,7 @@ uint16x4_t test_vcvt_n_u16_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vcvtq_n_u16_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1001,7 +1001,7 @@ float16x4_t test_vdiv_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vdivq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[DIV_I:%.*]] = fdiv <8 x half> [[A]], [[B]] // CHECK-NEXT: ret <8 x half> [[DIV_I]] @@ -1023,7 +1023,7 @@ float16x4_t test_vmax_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmaxq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1047,7 +1047,7 @@ float16x4_t test_vmaxnm_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmaxnmq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1071,7 +1071,7 @@ float16x4_t test_vmin_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vminq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1095,7 +1095,7 @@ float16x4_t test_vminnm_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vminnmq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1117,7 +1117,7 @@ float16x4_t test_vmul_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[MUL_I:%.*]] = fmul <8 x half> [[A]], [[B]] // CHECK-NEXT: ret <8 x half> [[MUL_I]] @@ -1139,7 +1139,7 @@ float16x4_t test_vmulx_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1164,7 +1164,7 @@ float16x4_t test_vpadd_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vpaddq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1189,7 +1189,7 @@ float16x4_t test_vpmax_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vpmaxq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1213,7 +1213,7 @@ float16x4_t test_vpmaxnm_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vpmaxnmq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1237,7 +1237,7 @@ float16x4_t test_vpmin_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vpminq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1261,7 +1261,7 @@ float16x4_t test_vpminnm_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vpminnmq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1286,7 +1286,7 @@ float16x4_t test_vrecps_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vrecpsq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1312,7 +1312,7 @@ float16x4_t test_vrsqrts_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vrsqrtsq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1335,7 +1335,7 @@ float16x4_t test_vsub_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vsubq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SUB_I:%.*]] = fsub <8 x half> [[A]], [[B]] // CHECK-NEXT: ret <8 x half> [[SUB_I]] @@ -1358,7 +1358,7 @@ float16x4_t test_vfma_f16(float16x4_t a, float16x4_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1385,7 +1385,7 @@ float16x4_t test_vfms_f16(float16x4_t a, float16x4_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG_I:%.*]] = fneg <8 x half> [[B]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> @@ -1416,7 +1416,7 @@ float16x4_t test_vfma_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_lane_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1433,7 +1433,7 @@ float16x8_t test_vfmaq_lane_f16(float16x8_t a, float16x8_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfma_laneq_f16 -// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> @@ -1450,7 +1450,7 @@ float16x4_t test_vfma_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -1469,7 +1469,7 @@ float16x8_t test_vfmaq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { // CHECK-LABEL: define {{[^@]+}}@test_vfma_n_f16 // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[C]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[C]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[C]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[C]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[C]], i32 3 @@ -1484,9 +1484,9 @@ float16x4_t test_vfma_n_f16(float16x4_t a, float16x4_t b, float16_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_n_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[C]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[C]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[C]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[C]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[C]], i32 3 @@ -1516,7 +1516,7 @@ float16_t test_vfmah_lane_f16(float16_t a, float16_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmah_laneq_f16 -// CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <8 x half> [[C]], i32 7 // CHECK-NEXT: [[TMP0:%.*]] = call half @llvm.fma.f16(half [[B]], half [[EXTRACT]], half [[A]]) @@ -1545,7 +1545,7 @@ float16x4_t test_vfms_lane_f16(float16x4_t a, float16x4_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_lane_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <4 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG:%.*]] = fneg <8 x half> [[B]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> @@ -1563,7 +1563,7 @@ float16x8_t test_vfmsq_lane_f16(float16x8_t a, float16x8_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfms_laneq_f16 -// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x half> [[B]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> @@ -1581,7 +1581,7 @@ float16x4_t test_vfms_laneq_f16(float16x4_t a, float16x4_t b, float16x8_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG:%.*]] = fneg <8 x half> [[B]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> @@ -1602,7 +1602,7 @@ float16x8_t test_vfmsq_laneq_f16(float16x8_t a, float16x8_t b, float16x8_t c) { // CHECK-SAME: (<4 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG:%.*]] = fneg <4 x half> [[B]] -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[C]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[C]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[C]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[C]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[C]], i32 3 @@ -1617,10 +1617,10 @@ float16x4_t test_vfms_n_f16(float16x4_t a, float16x4_t b, float16_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmsq_n_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], half noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FNEG:%.*]] = fneg <8 x half> [[B]] -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[C]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[C]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[C]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[C]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[C]], i32 3 @@ -1653,7 +1653,7 @@ float16_t test_vfmsh_lane_f16(float16_t a, float16_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmsh_laneq_f16 -// CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CONV:%.*]] = fpext half [[B]] to float // CHECK-NEXT: [[FNEG:%.*]] = fneg float [[CONV]] @@ -1680,7 +1680,7 @@ float16x4_t test_vmul_lane_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulq_lane_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> @@ -1693,7 +1693,7 @@ float16x8_t test_vmulq_lane_f16(float16x8_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmul_laneq_f16 -// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1706,7 +1706,7 @@ float16x4_t test_vmul_laneq_f16(float16x4_t a, float16x8_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulq_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1721,7 +1721,7 @@ float16x8_t test_vmulq_laneq_f16(float16x8_t a, float16x8_t b) { // CHECK-LABEL: define {{[^@]+}}@test_vmul_n_f16 // CHECK-SAME: (<4 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[B]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[B]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[B]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[B]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[B]], i32 3 @@ -1733,9 +1733,9 @@ float16x4_t test_vmul_n_f16(float16x4_t a, float16_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulq_n_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[B]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[B]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[B]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[B]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[B]], i32 3 @@ -1772,7 +1772,7 @@ float16_t test_vmulh_lane_f16(float16_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulh_laneq_f16 -// CHECK-SAME: (half noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (half noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[__REINT_850:%.*]] = alloca <8 x half>, align 16 // CHECK-NEXT: [[__REINT1_850:%.*]] = alloca i16, align 2 @@ -1807,7 +1807,7 @@ float16x4_t test_vmulx_lane_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_lane_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <4 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[B]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> @@ -1822,7 +1822,7 @@ float16x8_t test_vmulxq_lane_f16(float16x8_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulx_laneq_f16 -// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1837,7 +1837,7 @@ float16x4_t test_vmulx_laneq_f16(float16x4_t a, float16x8_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1854,7 +1854,7 @@ float16x8_t test_vmulxq_laneq_f16(float16x8_t a, float16x8_t b) { // CHECK-LABEL: define {{[^@]+}}@test_vmulx_n_f16 // CHECK-SAME: (<4 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[B]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[B]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[B]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[B]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[B]], i32 3 @@ -1868,9 +1868,9 @@ float16x4_t test_vmulx_n_f16(float16x4_t a, float16_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulxq_n_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], half noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[B]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[B]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[B]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[B]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[B]], i32 3 @@ -1899,7 +1899,7 @@ float16_t test_vmulxh_lane_f16(float16_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vmulxh_laneq_f16 -// CHECK-SAME: (half noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (half noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <8 x half> [[B]], i32 7 // CHECK-NEXT: [[VMULX:%.*]] = call half @llvm.aarch64.neon.fmulx.f16(half [[A]], half [[EXTRACT]]) @@ -1922,7 +1922,7 @@ float16_t test_vmaxv_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vmaxvq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VMAXV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1946,7 +1946,7 @@ float16_t test_vminv_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vminvq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VMINV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1970,7 +1970,7 @@ float16_t test_vmaxnmv_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vmaxnmvq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VMAXNMV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -1994,7 +1994,7 @@ float16_t test_vminnmv_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vminnmvq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[VMINNMV:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -2025,7 +2025,7 @@ float16x4_t test_vbsl_f16(uint16x4_t a, float16x4_t b, float16x4_t c) { } // CHECK-LABEL: define {{[^@]+}}@test_vbslq_f16 -// CHECK-SAME: (<8 x i16> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x i16> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]], <8 x half> noundef [[C:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -2067,7 +2067,7 @@ float16x4x2_t test_vzip_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vzipq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T:%.*]], align 16 // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T]], align 16 @@ -2113,7 +2113,7 @@ float16x4x2_t test_vuzp_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vuzpq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T:%.*]], align 16 // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T]], align 16 @@ -2159,7 +2159,7 @@ float16x4x2_t test_vtrn_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vtrnq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL_I:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T:%.*]], align 16 // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FLOAT16X8X2_T]], align 16 @@ -2184,7 +2184,7 @@ float16x8x2_t test_vtrnq_f16(float16x8_t a, float16x8_t b) { // CHECK-LABEL: define {{[^@]+}}@test_vmov_n_f16 // CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[A]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[A]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[A]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[A]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[A]], i32 3 @@ -2195,9 +2195,9 @@ float16x4_t test_vmov_n_f16(float16_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vmovq_n_f16 -// CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[A]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[A]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[A]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[A]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[A]], i32 3 @@ -2214,7 +2214,7 @@ float16x8_t test_vmovq_n_f16(float16_t a) { // CHECK-LABEL: define {{[^@]+}}@test_vdup_n_f16 // CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[A]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[A]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[A]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[A]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[A]], i32 3 @@ -2225,9 +2225,9 @@ float16x4_t test_vdup_n_f16(float16_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vdupq_n_f16 -// CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (half noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[A]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[A]], i32 0 // CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[A]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[A]], i32 2 // CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[A]], i32 3 @@ -2254,7 +2254,7 @@ float16x4_t test_vdup_lane_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vdupq_lane_f16 -// CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> @@ -2266,7 +2266,7 @@ float16x8_t test_vdupq_lane_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vdup_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -2278,7 +2278,7 @@ float16x4_t test_vdup_laneq_f16(float16x8_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vdupq_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> @@ -2304,7 +2304,7 @@ float16x4_t test_vext_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vextq_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[B]] to <16 x i8> @@ -2328,7 +2328,7 @@ float16x4_t test_vrev64_f16(float16x4_t a) { } // CHECK-LABEL: define {{[^@]+}}@test_vrev64q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[A]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2348,7 +2348,7 @@ float16x4_t test_vzip1_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vzip1q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2368,7 +2368,7 @@ float16x4_t test_vzip2_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vzip2q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2388,7 +2388,7 @@ float16x4_t test_vuzp1_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vuzp1q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2408,7 +2408,7 @@ float16x4_t test_vuzp2_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vuzp2q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2428,7 +2428,7 @@ float16x4_t test_vtrn1_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vtrn1q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2448,7 +2448,7 @@ float16x4_t test_vtrn2_f16(float16x4_t a, float16x4_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vtrn2q_f16 -// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[A:%.*]], <8 x half> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> [[A]], <8 x half> [[B]], <8 x i32> // CHECK-NEXT: ret <8 x half> [[SHUFFLE_I]] @@ -2458,7 +2458,7 @@ float16x8_t test_vtrn2q_f16(float16x8_t a, float16x8_t b) { } // CHECK-LABEL: define {{[^@]+}}@test_vduph_laneq_f16 -// CHECK-SAME: (<8 x half> noundef [[VEC:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<8 x half> noundef [[VEC:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x half> [[VEC]], i32 7 // CHECK-NEXT: ret half [[VGETQ_LANE]] diff --git a/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c b/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c index a1c0d8dd026abff8e3710ac6d13681a9b135efa5..161f1a75ca63078157dd2d22d7eb4e3250821b6f 100644 --- a/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c +++ b/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c @@ -38,19 +38,19 @@ float32x4_t test_vbfdotq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b){ // CHECK-LABEL: @test_vbfdot_lane_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_144:%.*]] = alloca <4 x bfloat>, align 8 -// CHECK-NEXT: [[__REINT1_144:%.*]] = alloca <2 x float>, align 8 -// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_144]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[__REINT_144]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP3]], <2 x i32> zeroinitializer -// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_144]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x bfloat>, ptr [[__REINT1_144]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <4 x bfloat> [[TMP5]] to <8 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_128:%.*]] = alloca <4 x bfloat>, align 8 +// CHECK-NEXT: [[__REINT1_128:%.*]] = alloca <2 x float>, align 8 +// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_128]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[__REINT_128]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[TMP0]] to <8 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP2]], <2 x float> [[TMP2]], <2 x i32> zeroinitializer +// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_128]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x bfloat>, ptr [[__REINT1_128]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x bfloat> [[TMP3]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <2 x float> [[VBFDOT3_I]] // float32x2_t test_vbfdot_lane_f32(float32x2_t r, bfloat16x4_t a, bfloat16x4_t b){ @@ -59,19 +59,19 @@ float32x2_t test_vbfdot_lane_f32(float32x2_t r, bfloat16x4_t a, bfloat16x4_t b){ // CHECK-LABEL: @test_vbfdotq_laneq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_146:%.*]] = alloca <8 x bfloat>, align 8 -// CHECK-NEXT: [[__REINT1_146:%.*]] = alloca <4 x float>, align 8 -// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_146]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[__REINT_146]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP3]], <4 x float> [[TMP3]], <4 x i32> -// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_146]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x bfloat>, ptr [[__REINT1_146]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x bfloat> [[TMP5]] to <16 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_130:%.*]] = alloca <8 x bfloat>, align 8 +// CHECK-NEXT: [[__REINT1_130:%.*]] = alloca <4 x float>, align 8 +// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_130]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[__REINT_130]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP2]], <4 x i32> +// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_130]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <8 x bfloat>, ptr [[__REINT1_130]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x bfloat> [[TMP3]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <4 x float> [[VBFDOT3_I]] // float32x4_t test_vbfdotq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { @@ -80,19 +80,19 @@ float32x4_t test_vbfdotq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b // CHECK-LABEL: @test_vbfdot_laneq_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_148:%.*]] = alloca <8 x bfloat>, align 8 -// CHECK-NEXT: [[__REINT1_148:%.*]] = alloca <2 x float>, align 8 -// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_148]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[__REINT_148]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x float> [[TMP1]] to <16 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP3]], <4 x float> [[TMP3]], <2 x i32> -// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_148]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <4 x bfloat>, ptr [[__REINT1_148]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <4 x bfloat> [[TMP5]] to <8 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_132:%.*]] = alloca <8 x bfloat>, align 8 +// CHECK-NEXT: [[__REINT1_132:%.*]] = alloca <2 x float>, align 8 +// CHECK-NEXT: store <8 x bfloat> [[B:%.*]], ptr [[__REINT_132]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[__REINT_132]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[TMP0]] to <16 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP2]], <2 x i32> +// CHECK-NEXT: store <2 x float> [[LANE]], ptr [[__REINT1_132]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x bfloat>, ptr [[__REINT1_132]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x float> [[R:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x bfloat> [[TMP3]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v4bf16(<2 x float> [[R]], <4 x bfloat> [[A]], <4 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <2 x float> [[VBFDOT3_I]] // float32x2_t test_vbfdot_laneq_f32(float32x2_t r, bfloat16x4_t a, bfloat16x8_t b) { @@ -101,19 +101,19 @@ float32x2_t test_vbfdot_laneq_f32(float32x2_t r, bfloat16x4_t a, bfloat16x8_t b) // CHECK-LABEL: @test_vbfdotq_lane_f32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[__REINT_142:%.*]] = alloca <4 x bfloat>, align 8 -// CHECK-NEXT: [[__REINT1_142:%.*]] = alloca <4 x float>, align 8 -// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_142]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[__REINT_142]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x float> [[TMP1]] to <8 x i8> -// CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float> -// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP3]], <4 x i32> zeroinitializer -// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_142]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load <8 x bfloat>, ptr [[__REINT1_142]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP7:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x bfloat> [[TMP5]] to <16 x i8> -// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP5]]) +// CHECK-NEXT: [[__REINT_126:%.*]] = alloca <4 x bfloat>, align 8 +// CHECK-NEXT: [[__REINT1_126:%.*]] = alloca <4 x float>, align 8 +// CHECK-NEXT: store <4 x bfloat> [[B:%.*]], ptr [[__REINT_126]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[__REINT_126]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[TMP0]] to <8 x i8> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[TMP2]], <2 x float> [[TMP2]], <4 x i32> zeroinitializer +// CHECK-NEXT: store <4 x float> [[LANE]], ptr [[__REINT1_126]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <8 x bfloat>, ptr [[__REINT1_126]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP6:%.*]] = bitcast <8 x bfloat> [[TMP3]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v8bf16(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[TMP3]]) // CHECK-NEXT: ret <4 x float> [[VBFDOT3_I]] // float32x4_t test_vbfdotq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { @@ -125,9 +125,9 @@ float32x4_t test_vbfdotq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VBFMMLAQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmmla(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) -// CHECK-NEXT: [[VBFMMLAQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMMLAQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMMLAQ_V3_I]] +// CHECK-NEXT: [[VBFMMLAQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmmla(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) +// CHECK-NEXT: [[VBFMMLAQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMMLAQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMMLAQ_F323_I]] // float32x4_t test_vbfmmlaq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmmlaq_f32(r, a, b); @@ -138,9 +138,9 @@ float32x4_t test_vbfmmlaq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALBQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) -// CHECK-NEXT: [[VBFMLALBQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_V3_I]] +// CHECK-NEXT: [[VBFMLALBQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) +// CHECK-NEXT: [[VBFMLALBQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_F323_I]] // float32x4_t test_vbfmlalbq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlalbq_f32(r, a, b); @@ -151,9 +151,9 @@ float32x4_t test_vbfmlalbq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALTQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) -// CHECK-NEXT: [[VBFMLALTQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_V3_I]] +// CHECK-NEXT: [[VBFMLALTQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[B]]) +// CHECK-NEXT: [[VBFMLALTQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_F323_I]] // float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlaltq_f32(r, a, b); @@ -162,7 +162,7 @@ float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-LABEL: @test_vbfmlalbq_lane_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[B:%.*]], i32 0 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGET_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGET_LANE]], i32 0 // CHECK-NEXT: [[VGET_LANE3:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGET_LANE3]], i32 1 // CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 @@ -180,9 +180,9 @@ float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALBQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALBQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_V3_I]] +// CHECK-NEXT: [[VBFMLALBQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALBQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_F323_I]] // float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { return vbfmlalbq_lane_f32(r, a, b, 0); @@ -191,7 +191,7 @@ float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-LABEL: @test_vbfmlalbq_laneq_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 3 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGET_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGET_LANE]], i32 0 // CHECK-NEXT: [[VGET_LANE3:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGET_LANE3]], i32 1 // CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 @@ -209,9 +209,9 @@ float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALBQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALBQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_V3_I]] +// CHECK-NEXT: [[VBFMLALBQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALBQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALBQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALBQ_F323_I]] // float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlalbq_laneq_f32(r, a, b, 3); @@ -220,7 +220,7 @@ float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t // CHECK-LABEL: @test_vbfmlaltq_lane_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[B:%.*]], i32 0 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGET_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGET_LANE]], i32 0 // CHECK-NEXT: [[VGET_LANE3:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGET_LANE3]], i32 1 // CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <4 x bfloat> [[B]], i32 0 @@ -238,9 +238,9 @@ float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALTQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALTQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_V3_I]] +// CHECK-NEXT: [[VBFMLALTQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALTQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_F323_I]] // float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { return vbfmlaltq_lane_f32(r, a, b, 0); @@ -249,7 +249,7 @@ float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-LABEL: @test_vbfmlaltq_laneq_f32( // CHECK-NEXT: entry: // CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 3 -// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> undef, bfloat [[VGET_LANE]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <8 x bfloat> poison, bfloat [[VGET_LANE]], i32 0 // CHECK-NEXT: [[VGET_LANE3:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 // CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <8 x bfloat> [[VECINIT]], bfloat [[VGET_LANE3]], i32 1 // CHECK-NEXT: [[VGET_LANE8:%.*]] = extractelement <8 x bfloat> [[B]], i32 3 @@ -267,9 +267,9 @@ float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[R:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> -// CHECK-NEXT: [[VBFMLALTQ_V3_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) -// CHECK-NEXT: [[VBFMLALTQ_V4_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_V3_I]] to <16 x i8> -// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_V3_I]] +// CHECK-NEXT: [[VBFMLALTQ_F323_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt(<4 x float> [[R]], <8 x bfloat> [[A]], <8 x bfloat> [[VECINIT35]]) +// CHECK-NEXT: [[VBFMLALTQ_F324_I:%.*]] = bitcast <4 x float> [[VBFMLALTQ_F323_I]] to <16 x i8> +// CHECK-NEXT: ret <4 x float> [[VBFMLALTQ_F323_I]] // float32x4_t test_vbfmlaltq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { return vbfmlaltq_laneq_f32(r, a, b, 3); diff --git a/clang/test/CodeGen/arm-bf16-getset-intrinsics.c b/clang/test/CodeGen/arm-bf16-getset-intrinsics.c index df2b6a94274ede6ba7d3c945cb2b0c677de3a53e..b87d0e8eb68bb4448df50dbb19f89cbc860eb46e 100644 --- a/clang/test/CodeGen/arm-bf16-getset-intrinsics.c +++ b/clang/test/CodeGen/arm-bf16-getset-intrinsics.c @@ -19,7 +19,7 @@ bfloat16x4_t test_vcreate_bf16(uint64_t a) { // CHECK-LABEL: @test_vdup_n_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x bfloat> undef, bfloat [[V:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x bfloat> poison, bfloat [[V:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x bfloat> [[VECINIT_I]], bfloat [[V]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x bfloat> [[VECINIT1_I]], bfloat [[V]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x bfloat> [[VECINIT2_I]], bfloat [[V]], i32 3 @@ -31,7 +31,7 @@ bfloat16x4_t test_vdup_n_bf16(bfloat16_t v) { // CHECK-LABEL: @test_vdupq_n_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x bfloat> undef, bfloat [[V:%.*]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x bfloat> poison, bfloat [[V:%.*]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x bfloat> [[VECINIT_I]], bfloat [[V]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x bfloat> [[VECINIT1_I]], bfloat [[V]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x bfloat> [[VECINIT2_I]], bfloat [[V]], i32 3 diff --git a/clang/test/CodeGen/arm-bf16-params-returns.c b/clang/test/CodeGen/arm-bf16-params-returns.c index 2d33e3f45eacf75fc0c5528f45ea2840635b8857..21be0bb151697aee438103bff80ec890134b76c2 100644 --- a/clang/test/CodeGen/arm-bf16-params-returns.c +++ b/clang/test/CodeGen/arm-bf16-params-returns.c @@ -11,7 +11,7 @@ __bf16 test_ret_bf16(__bf16 v) { return v; } -// CHECK32-HARD: define{{.*}} arm_aapcs_vfpcc bfloat @test_ret_bf16(bfloat noundef returned %v) {{.*}} { +// CHECK32-HARD: define{{.*}} arm_aapcs_vfpcc noundef bfloat @test_ret_bf16(bfloat noundef returned %v) {{.*}} { // CHECK32-HARD: ret bfloat %v // CHECK32-SOFTFP: define{{.*}} bfloat @test_ret_bf16(bfloat noundef returned %v) {{.*}} { // CHECK32-SOFTFP: ret bfloat %v @@ -23,11 +23,11 @@ __bf16 test_ret_bf16(__bf16 v) { bfloat16x4_t test_ret_bf16x4_t(bfloat16x4_t v) { return v; } -// CHECK32-HARD: define{{.*}} arm_aapcs_vfpcc <4 x bfloat> @test_ret_bf16x4_t(<4 x bfloat> noundef returned %v) {{.*}} { +// CHECK32-HARD: define{{.*}} arm_aapcs_vfpcc noundef <4 x bfloat> @test_ret_bf16x4_t(<4 x bfloat> noundef returned %v) {{.*}} { // CHECK32-HARD: ret <4 x bfloat> %v -// CHECK32-SOFTFP: define{{.*}} <2 x i32> @test_ret_bf16x4_t(<2 x i32> [[V0:.*]]) {{.*}} { +// CHECK32-SOFTFP: define{{.*}} noundef <2 x i32> @test_ret_bf16x4_t(<2 x i32> [[V0:.*]]) {{.*}} { // CHECK32-SOFTFP: ret <2 x i32> %v -// CHECK64NEON: define{{.*}} <4 x bfloat> @test_ret_bf16x4_t(<4 x bfloat> noundef returned %v) {{.*}} { +// CHECK64NEON: define{{.*}} noundef <4 x bfloat> @test_ret_bf16x4_t(<4 x bfloat> noundef returned %v) {{.*}} { // CHECK64NEON: ret <4 x bfloat> %v #endif \ No newline at end of file diff --git a/clang/test/CodeGen/arm-neon-fma.c b/clang/test/CodeGen/arm-neon-fma.c index 0280686a4cd11c413964d6814e38c7dc9ea5228c..682eda9750c81a94c2a70422cd6f457ec76e3138 100644 --- a/clang/test/CodeGen/arm-neon-fma.c +++ b/clang/test/CodeGen/arm-neon-fma.c @@ -24,7 +24,7 @@ float32x2_t test_fma_order(float32x2_t accum, float32x2_t lhs, float32x2_t rhs) } // CHECK-LABEL: define {{[^@]+}}@test_fmaq_order -// CHECK-SAME: (<4 x float> noundef [[ACCUM:%.*]], <4 x float> noundef [[LHS:%.*]], <4 x float> noundef [[RHS:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK-SAME: (<4 x float> noundef [[ACCUM:%.*]], <4 x float> noundef [[LHS:%.*]], <4 x float> noundef [[RHS:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[ACCUM]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[LHS]] to <16 x i8> @@ -39,7 +39,7 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) // CHECK-LABEL: define {{[^@]+}}@test_vfma_n_f32 // CHECK-SAME: (<2 x float> noundef [[A:%.*]], <2 x float> noundef [[B:%.*]], float noundef [[N:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float [[N]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float [[N]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float [[N]], i32 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <8 x i8> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[B]] to <8 x i8> @@ -52,9 +52,9 @@ float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { } // CHECK-LABEL: define {{[^@]+}}@test_vfmaq_n_f32 -// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], float noundef [[N:%.*]]) #[[ATTR1]] { +// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]], float noundef [[N:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[N]], i32 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[N]], i32 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[N]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[N]], i32 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[N]], i32 3 diff --git a/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c b/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c index d09687576aba0db0fd09c0b1138fe01b1b80d7fe..477da3a9e20517422683d0bfbefa5603f7b83dea 100644 --- a/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c +++ b/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c @@ -793,7 +793,7 @@ float16x8_t test_vmulq_lane_f16(float16x8_t a, float16x4_t b) { } // CHECK-LABEL: test_vmul_n_f16 -// CHECK: [[TMP0:%.*]] = insertelement <4 x half> undef, half [[b:%.*]], i32 0 +// CHECK: [[TMP0:%.*]] = insertelement <4 x half> poison, half [[b:%.*]], i32 0 // CHECK: [[TMP1:%.*]] = insertelement <4 x half> [[TMP0]], half [[b]], i32 1 // CHECK: [[TMP2:%.*]] = insertelement <4 x half> [[TMP1]], half [[b]], i32 2 // CHECK: [[TMP3:%.*]] = insertelement <4 x half> [[TMP2]], half [[b]], i32 3 @@ -804,7 +804,7 @@ float16x4_t test_vmul_n_f16(float16x4_t a, float16_t b) { } // CHECK-LABEL: test_vmulq_n_f16 -// CHECK: [[TMP0:%.*]] = insertelement <8 x half> undef, half [[b:%.*]], i32 0 +// CHECK: [[TMP0:%.*]] = insertelement <8 x half> poison, half [[b:%.*]], i32 0 // CHECK: [[TMP1:%.*]] = insertelement <8 x half> [[TMP0]], half [[b]], i32 1 // CHECK: [[TMP2:%.*]] = insertelement <8 x half> [[TMP1]], half [[b]], i32 2 // CHECK: [[TMP3:%.*]] = insertelement <8 x half> [[TMP2]], half [[b]], i32 3 @@ -895,7 +895,7 @@ float16x8x2_t test_vtrnq_f16(float16x8_t a, float16x8_t b) { } // CHECK-LABEL: test_vmov_n_f16 -// CHECK: [[TMP0:%.*]] = insertelement <4 x half> undef, half [[ARG:%.*]], i32 0 +// CHECK: [[TMP0:%.*]] = insertelement <4 x half> poison, half [[ARG:%.*]], i32 0 // CHECK: [[TMP1:%.*]] = insertelement <4 x half> [[TMP0]], half [[ARG]], i32 1 // CHECK: [[TMP2:%.*]] = insertelement <4 x half> [[TMP1]], half [[ARG]], i32 2 // CHECK: [[TMP3:%.*]] = insertelement <4 x half> [[TMP2]], half [[ARG]], i32 3 @@ -905,7 +905,7 @@ float16x4_t test_vmov_n_f16(float16_t a) { } // CHECK-LABEL: test_vmovq_n_f16 -// CHECK: [[TMP0:%.*]] = insertelement <8 x half> undef, half [[ARG:%.*]], i32 0 +// CHECK: [[TMP0:%.*]] = insertelement <8 x half> poison, half [[ARG:%.*]], i32 0 // CHECK: [[TMP1:%.*]] = insertelement <8 x half> [[TMP0]], half [[ARG]], i32 1 // CHECK: [[TMP2:%.*]] = insertelement <8 x half> [[TMP1]], half [[ARG]], i32 2 // CHECK: [[TMP3:%.*]] = insertelement <8 x half> [[TMP2]], half [[ARG]], i32 3 @@ -919,7 +919,7 @@ float16x8_t test_vmovq_n_f16(float16_t a) { } // CHECK-LABEL: test_vdup_n_f16 -// CHECK: [[TMP0:%.*]] = insertelement <4 x half> undef, half [[ARG:%.*]], i32 0 +// CHECK: [[TMP0:%.*]] = insertelement <4 x half> poison, half [[ARG:%.*]], i32 0 // CHECK: [[TMP1:%.*]] = insertelement <4 x half> [[TMP0]], half [[ARG]], i32 1 // CHECK: [[TMP2:%.*]] = insertelement <4 x half> [[TMP1]], half [[ARG]], i32 2 // CHECK: [[TMP3:%.*]] = insertelement <4 x half> [[TMP2]], half [[ARG]], i32 3 @@ -929,7 +929,7 @@ float16x4_t test_vdup_n_f16(float16_t a) { } // CHECK-LABEL: test_vdupq_n_f16 -// CHECK: [[TMP0:%.*]] = insertelement <8 x half> undef, half [[ARG:%.*]], i32 0 +// CHECK: [[TMP0:%.*]] = insertelement <8 x half> poison, half [[ARG:%.*]], i32 0 // CHECK: [[TMP1:%.*]] = insertelement <8 x half> [[TMP0]], half [[ARG]], i32 1 // CHECK: [[TMP2:%.*]] = insertelement <8 x half> [[TMP1]], half [[ARG]], i32 2 // CHECK: [[TMP3:%.*]] = insertelement <8 x half> [[TMP2]], half [[ARG]], i32 3 diff --git a/clang/test/CodeGen/arm-vector_type-params-returns.c b/clang/test/CodeGen/arm-vector_type-params-returns.c new file mode 100644 index 0000000000000000000000000000000000000000..a55aba9ce0665199cba88daff0999e675f685084 --- /dev/null +++ b/clang/test/CodeGen/arm-vector_type-params-returns.c @@ -0,0 +1,136 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3 + +// RUN: %clang_cc1 -DSVE_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s +// RUN: %clang_cc1 -DSVE_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s + +// RUN: %clang_cc1 -DNEON_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s +// RUN: %clang_cc1 -DNEON_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s + +// RUN: %clang_cc1 -DSVE_HEADER -DNEON_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s +// RUN: %clang_cc1 -DSVE_HEADER -DNEON_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s + +// RUN: %clang_cc1 -DNEON_HEADER -DSVE_HEADER2 -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s +// RUN: %clang_cc1 -DNEON_HEADER -DSVE_HEADER2 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef SVE_HEADER + #include +#endif + +#ifdef NEON_HEADER + #include +#endif + +#ifdef SVE_HEADER_2 + #include +#endif + +// function return types +// CHECK-LABEL: define dso_local noundef <8 x half> @test_ret_v8f16( +// CHECK-SAME: <8 x half> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <8 x half> [[V]] +// +float16x8_t test_ret_v8f16(float16x8_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <4 x float> @test_ret_v4f32( +// CHECK-SAME: <4 x float> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <4 x float> [[V]] +// +float32x4_t test_ret_v4f32(float32x4_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <2 x double> @test_ret_v2f64( +// CHECK-SAME: <2 x double> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <2 x double> [[V]] +// +float64x2_t test_ret_v2f64(float64x2_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <8 x bfloat> @test_ret_v8bf16( +// CHECK-SAME: <8 x bfloat> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <8 x bfloat> [[V]] +// +bfloat16x8_t test_ret_v8bf16(bfloat16x8_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <16 x i8> @test_ret_v16s8( +// CHECK-SAME: <16 x i8> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <16 x i8> [[V]] +// +int8x16_t test_ret_v16s8(int8x16_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <8 x i16> @test_ret_v8s16( +// CHECK-SAME: <8 x i16> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <8 x i16> [[V]] +// +int16x8_t test_ret_v8s16(int16x8_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <4 x i32> @test_ret_v32s4( +// CHECK-SAME: <4 x i32> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <4 x i32> [[V]] +// +int32x4_t test_ret_v32s4(int32x4_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <2 x i64> @test_ret_v64s2( +// CHECK-SAME: <2 x i64> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <2 x i64> [[V]] +// +int64x2_t test_ret_v64s2(int64x2_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <16 x i8> @test_ret_v16u8( +// CHECK-SAME: <16 x i8> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <16 x i8> [[V]] +// +uint8x16_t test_ret_v16u8(uint8x16_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <8 x i16> @test_ret_v8u16( +// CHECK-SAME: <8 x i16> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <8 x i16> [[V]] +// +uint16x8_t test_ret_v8u16(uint16x8_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <4 x i32> @test_ret_v32u4( +// CHECK-SAME: <4 x i32> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <4 x i32> [[V]] +// +uint32x4_t test_ret_v32u4(uint32x4_t v) { + return v; +} + +// CHECK-LABEL: define dso_local noundef <2 x i64> @test_ret_v64u2( +// CHECK-SAME: <2 x i64> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret <2 x i64> [[V]] +// +uint64x2_t test_ret_v64u2(uint64x2_t v) { + return v; +} diff --git a/clang/test/CodeGen/arm64_vdupq_n_f64.c b/clang/test/CodeGen/arm64_vdupq_n_f64.c index 8618b255cbcd5edaae0f90e6006f9e642ad26eac..35d4457cd31ea54cbbcb331e4f4489d566706222 100644 --- a/clang/test/CodeGen/arm64_vdupq_n_f64.c +++ b/clang/test/CodeGen/arm64_vdupq_n_f64.c @@ -7,7 +7,7 @@ // vdupq_n_f64 -> dup.2d v0, v0[0] // // CHECK-LABEL: define{{.*}} <2 x double> @test_vdupq_n_f64(double noundef %w) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double %w, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double %w, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double %w, i32 1 // CHECK: ret <2 x double> [[VECINIT1_I]] float64x2_t test_vdupq_n_f64(float64_t w) { @@ -17,7 +17,7 @@ float64x2_t test_vdupq_n_f64(float64_t w) { // might as well test this while we're here // vdupq_n_f32 -> dup.4s v0, v0[0] // CHECK-LABEL: define{{.*}} <4 x float> @test_vdupq_n_f32(float noundef %w) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %w, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float %w, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %w, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %w, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %w, i32 3 @@ -38,7 +38,7 @@ float64x2_t test_vdupq_lane_f64(float64x1_t V) { // vmovq_n_f64 -> dup Vd.2d,X0 // CHECK-LABEL: define{{.*}} <2 x double> @test_vmovq_n_f64(double noundef %w) #0 { -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double %w, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double %w, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double %w, i32 1 // CHECK: ret <2 x double> [[VECINIT1_I]] float64x2_t test_vmovq_n_f64(float64_t w) { @@ -47,7 +47,7 @@ float64x2_t test_vmovq_n_f64(float64_t w) { // CHECK-LABEL: define{{.*}} <4 x half> @test_vmov_n_f16(ptr noundef %a1) #0 { // CHECK: [[TMP0:%.*]] = load half, ptr %a1, align 2 -// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP0]], i32 0 +// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP0]], i32 0 // CHECK: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP0]], i32 1 // CHECK: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[TMP0]], i32 2 // CHECK: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[TMP0]], i32 3 @@ -64,7 +64,7 @@ float64x1_t test_vmov_n_f64(float64_t a1) { // CHECK-LABEL: define{{.*}} <8 x half> @test_vmovq_n_f16(ptr noundef %a1) #0 { // CHECK: [[TMP0:%.*]] = load half, ptr %a1, align 2 -// CHECK: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP0]], i32 0 +// CHECK: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP0]], i32 0 // CHECK: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP0]], i32 1 // CHECK: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[TMP0]], i32 2 // CHECK: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[TMP0]], i32 3 diff --git a/clang/test/CodeGen/arm_neon_intrinsics.c b/clang/test/CodeGen/arm_neon_intrinsics.c index 67b0b5779a5bc148eb12619dd10c2fede2d0536f..5757f89c0d7d025c038d07f9a479b37c8eb1fda3 100644 --- a/clang/test/CodeGen/arm_neon_intrinsics.c +++ b/clang/test/CodeGen/arm_neon_intrinsics.c @@ -2650,7 +2650,7 @@ uint64x2_t test_vdupq_lane_u64(uint64x1_t a) { } // CHECK-LABEL: @test_vdup_n_u8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -2664,7 +2664,7 @@ uint8x8_t test_vdup_n_u8(uint8_t a) { } // CHECK-LABEL: @test_vdup_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -2674,7 +2674,7 @@ uint16x4_t test_vdup_n_u16(uint16_t a) { } // CHECK-LABEL: @test_vdup_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: ret <2 x i32> [[VECINIT1_I]] uint32x2_t test_vdup_n_u32(uint32_t a) { @@ -2682,7 +2682,7 @@ uint32x2_t test_vdup_n_u32(uint32_t a) { } // CHECK-LABEL: @test_vdup_n_s8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -2696,7 +2696,7 @@ int8x8_t test_vdup_n_s8(int8_t a) { } // CHECK-LABEL: @test_vdup_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -2706,7 +2706,7 @@ int16x4_t test_vdup_n_s16(int16_t a) { } // CHECK-LABEL: @test_vdup_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: ret <2 x i32> [[VECINIT1_I]] int32x2_t test_vdup_n_s32(int32_t a) { @@ -2714,7 +2714,7 @@ int32x2_t test_vdup_n_s32(int32_t a) { } // CHECK-LABEL: @test_vdup_n_p8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -2728,7 +2728,7 @@ poly8x8_t test_vdup_n_p8(poly8_t a) { } // CHECK-LABEL: @test_vdup_n_p16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -2739,7 +2739,7 @@ poly16x4_t test_vdup_n_p16(poly16_t a) { // CHECK-LABEL: @test_vdup_n_f16( // CHECK: [[TMP0:%.*]] = load half, ptr %a, align 2 -// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP0]], i32 0 +// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP0]], i32 0 // CHECK: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP0]], i32 1 // CHECK: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[TMP0]], i32 2 // CHECK: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[TMP0]], i32 3 @@ -2749,7 +2749,7 @@ float16x4_t test_vdup_n_f16(float16_t *a) { } // CHECK-LABEL: @test_vdup_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %a, i32 1 // CHECK: ret <2 x float> [[VECINIT1_I]] float32x2_t test_vdup_n_f32(float32_t a) { @@ -2757,7 +2757,7 @@ float32x2_t test_vdup_n_f32(float32_t a) { } // CHECK-LABEL: @test_vdupq_n_u8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -2779,7 +2779,7 @@ uint8x16_t test_vdupq_n_u8(uint8_t a) { } // CHECK-LABEL: @test_vdupq_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -2793,7 +2793,7 @@ uint16x8_t test_vdupq_n_u16(uint16_t a) { } // CHECK-LABEL: @test_vdupq_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %a, i32 3 @@ -2803,7 +2803,7 @@ uint32x4_t test_vdupq_n_u32(uint32_t a) { } // CHECK-LABEL: @test_vdupq_n_s8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -2825,7 +2825,7 @@ int8x16_t test_vdupq_n_s8(int8_t a) { } // CHECK-LABEL: @test_vdupq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -2839,7 +2839,7 @@ int16x8_t test_vdupq_n_s16(int16_t a) { } // CHECK-LABEL: @test_vdupq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %a, i32 3 @@ -2849,7 +2849,7 @@ int32x4_t test_vdupq_n_s32(int32_t a) { } // CHECK-LABEL: @test_vdupq_n_p8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -2871,7 +2871,7 @@ poly8x16_t test_vdupq_n_p8(poly8_t a) { } // CHECK-LABEL: @test_vdupq_n_p16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -2886,7 +2886,7 @@ poly16x8_t test_vdupq_n_p16(poly16_t a) { // CHECK-LABEL: @test_vdupq_n_f16( // CHECK: [[TMP0:%.*]] = load half, ptr %a, align 2 -// CHECK: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP0]], i32 0 +// CHECK: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP0]], i32 0 // CHECK: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP0]], i32 1 // CHECK: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[TMP0]], i32 2 // CHECK: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[TMP0]], i32 3 @@ -2900,7 +2900,7 @@ float16x8_t test_vdupq_n_f16(float16_t *a) { } // CHECK-LABEL: @test_vdupq_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %a, i32 3 @@ -2910,7 +2910,7 @@ float32x4_t test_vdupq_n_f32(float32_t a) { } // CHECK-LABEL: @test_vdup_n_s64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> poison, i64 %a, i32 0 // CHECK: [[ADD_I:%.*]] = add <1 x i64> [[VECINIT_I]], [[VECINIT_I]] // CHECK: ret <1 x i64> [[ADD_I]] int64x1_t test_vdup_n_s64(int64_t a) { @@ -2919,7 +2919,7 @@ int64x1_t test_vdup_n_s64(int64_t a) { } // CHECK-LABEL: @test_vdup_n_u64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> poison, i64 %a, i32 0 // CHECK: [[ADD_I:%.*]] = add <1 x i64> [[VECINIT_I]], [[VECINIT_I]] // CHECK: ret <1 x i64> [[ADD_I]] int64x1_t test_vdup_n_u64(uint64_t a) { @@ -2928,7 +2928,7 @@ int64x1_t test_vdup_n_u64(uint64_t a) { } // CHECK-LABEL: @test_vdupq_n_s64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1 // CHECK: [[ADD_I:%.*]] = add <2 x i64> [[VECINIT1_I]], [[VECINIT1_I]] // CHECK: ret <2 x i64> [[ADD_I]] @@ -2938,7 +2938,7 @@ int64x2_t test_vdupq_n_s64(int64_t a) { } // CHECK-LABEL: @test_vdupq_n_u64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1 // CHECK: [[ADD_I:%.*]] = add <2 x i64> [[VECINIT1_I]], [[VECINIT1_I]] // CHECK: ret <2 x i64> [[ADD_I]] @@ -6761,7 +6761,7 @@ uint64x2_t test_vmlal_lane_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) { } // CHECK-LABEL: @test_vmlal_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -6775,7 +6775,7 @@ int32x4_t test_vmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) { } // CHECK-LABEL: @test_vmlal_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %b to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -6787,7 +6787,7 @@ int64x2_t test_vmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) { } // CHECK-LABEL: @test_vmlal_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -6801,7 +6801,7 @@ uint32x4_t test_vmlal_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) { } // CHECK-LABEL: @test_vmlal_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %b to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -6923,7 +6923,7 @@ float32x4_t test_vmlaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t c) { } // CHECK-LABEL: @test_vmla_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -6935,7 +6935,7 @@ int16x4_t test_vmla_n_s16(int16x4_t a, int16x4_t b, int16_t c) { } // CHECK-LABEL: @test_vmla_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[MUL_I:%.*]] = mul <2 x i32> %b, [[VECINIT1_I]] // CHECK: [[ADD_I:%.*]] = add <2 x i32> %a, [[MUL_I]] @@ -6945,7 +6945,7 @@ int32x2_t test_vmla_n_s32(int32x2_t a, int32x2_t b, int32_t c) { } // CHECK-LABEL: @test_vmla_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -6957,7 +6957,7 @@ uint16x4_t test_vmla_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) { } // CHECK-LABEL: @test_vmla_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[MUL_I:%.*]] = mul <2 x i32> %b, [[VECINIT1_I]] // CHECK: [[ADD_I:%.*]] = add <2 x i32> %a, [[MUL_I]] @@ -6967,7 +6967,7 @@ uint32x2_t test_vmla_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) { } // CHECK-LABEL: @test_vmla_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %c, i32 1 // CHECK: [[MUL_I:%.*]] = fmul <2 x float> %b, [[VECINIT1_I]] // CHECK: [[ADD_I:%.*]] = fadd <2 x float> %a, [[MUL_I]] @@ -6977,7 +6977,7 @@ float32x2_t test_vmla_n_f32(float32x2_t a, float32x2_t b, float32_t c) { } // CHECK-LABEL: @test_vmlaq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -6993,7 +6993,7 @@ int16x8_t test_vmlaq_n_s16(int16x8_t a, int16x8_t b, int16_t c) { } // CHECK-LABEL: @test_vmlaq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %c, i32 3 @@ -7005,7 +7005,7 @@ int32x4_t test_vmlaq_n_s32(int32x4_t a, int32x4_t b, int32_t c) { } // CHECK-LABEL: @test_vmlaq_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7021,7 +7021,7 @@ uint16x8_t test_vmlaq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) { } // CHECK-LABEL: @test_vmlaq_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %c, i32 3 @@ -7033,7 +7033,7 @@ uint32x4_t test_vmlaq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) { } // CHECK-LABEL: @test_vmlaq_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %c, i32 3 @@ -7265,7 +7265,7 @@ uint64x2_t test_vmlsl_lane_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) { } // CHECK-LABEL: @test_vmlsl_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7279,7 +7279,7 @@ int32x4_t test_vmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) { } // CHECK-LABEL: @test_vmlsl_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %b to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -7291,7 +7291,7 @@ int64x2_t test_vmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) { } // CHECK-LABEL: @test_vmlsl_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7305,7 +7305,7 @@ uint32x4_t test_vmlsl_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) { } // CHECK-LABEL: @test_vmlsl_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %b to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -7427,7 +7427,7 @@ float32x4_t test_vmlsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t c) { } // CHECK-LABEL: @test_vmls_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7439,7 +7439,7 @@ int16x4_t test_vmls_n_s16(int16x4_t a, int16x4_t b, int16_t c) { } // CHECK-LABEL: @test_vmls_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[MUL_I:%.*]] = mul <2 x i32> %b, [[VECINIT1_I]] // CHECK: [[SUB_I:%.*]] = sub <2 x i32> %a, [[MUL_I]] @@ -7449,7 +7449,7 @@ int32x2_t test_vmls_n_s32(int32x2_t a, int32x2_t b, int32_t c) { } // CHECK-LABEL: @test_vmls_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7461,7 +7461,7 @@ uint16x4_t test_vmls_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) { } // CHECK-LABEL: @test_vmls_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[MUL_I:%.*]] = mul <2 x i32> %b, [[VECINIT1_I]] // CHECK: [[SUB_I:%.*]] = sub <2 x i32> %a, [[MUL_I]] @@ -7471,7 +7471,7 @@ uint32x2_t test_vmls_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) { } // CHECK-LABEL: @test_vmls_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %c, i32 1 // CHECK: [[MUL_I:%.*]] = fmul <2 x float> %b, [[VECINIT1_I]] // CHECK: [[SUB_I:%.*]] = fsub <2 x float> %a, [[MUL_I]] @@ -7481,7 +7481,7 @@ float32x2_t test_vmls_n_f32(float32x2_t a, float32x2_t b, float32_t c) { } // CHECK-LABEL: @test_vmlsq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7497,7 +7497,7 @@ int16x8_t test_vmlsq_n_s16(int16x8_t a, int16x8_t b, int16_t c) { } // CHECK-LABEL: @test_vmlsq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %c, i32 3 @@ -7509,7 +7509,7 @@ int32x4_t test_vmlsq_n_s32(int32x4_t a, int32x4_t b, int32_t c) { } // CHECK-LABEL: @test_vmlsq_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -7525,7 +7525,7 @@ uint16x8_t test_vmlsq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) { } // CHECK-LABEL: @test_vmlsq_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %c, i32 3 @@ -7537,7 +7537,7 @@ uint32x4_t test_vmlsq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) { } // CHECK-LABEL: @test_vmlsq_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %c, i32 3 @@ -7643,7 +7643,7 @@ uint32x2_t test_vmovn_u64(uint64x2_t a) { } // CHECK-LABEL: @test_vmov_n_u8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -7657,7 +7657,7 @@ uint8x8_t test_vmov_n_u8(uint8_t a) { } // CHECK-LABEL: @test_vmov_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -7667,7 +7667,7 @@ uint16x4_t test_vmov_n_u16(uint16_t a) { } // CHECK-LABEL: @test_vmov_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: ret <2 x i32> [[VECINIT1_I]] uint32x2_t test_vmov_n_u32(uint32_t a) { @@ -7675,7 +7675,7 @@ uint32x2_t test_vmov_n_u32(uint32_t a) { } // CHECK-LABEL: @test_vmov_n_s8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -7689,7 +7689,7 @@ int8x8_t test_vmov_n_s8(int8_t a) { } // CHECK-LABEL: @test_vmov_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -7699,7 +7699,7 @@ int16x4_t test_vmov_n_s16(int16_t a) { } // CHECK-LABEL: @test_vmov_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: ret <2 x i32> [[VECINIT1_I]] int32x2_t test_vmov_n_s32(int32_t a) { @@ -7707,7 +7707,7 @@ int32x2_t test_vmov_n_s32(int32_t a) { } // CHECK-LABEL: @test_vmov_n_p8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -7721,7 +7721,7 @@ poly8x8_t test_vmov_n_p8(poly8_t a) { } // CHECK-LABEL: @test_vmov_n_p16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -7732,7 +7732,7 @@ poly16x4_t test_vmov_n_p16(poly16_t a) { // CHECK-LABEL: @test_vmov_n_f16( // CHECK: [[TMP0:%.*]] = load half, ptr %a, align 2 -// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> undef, half [[TMP0]], i32 0 +// CHECK: [[VECINIT:%.*]] = insertelement <4 x half> poison, half [[TMP0]], i32 0 // CHECK: [[VECINIT1:%.*]] = insertelement <4 x half> [[VECINIT]], half [[TMP0]], i32 1 // CHECK: [[VECINIT2:%.*]] = insertelement <4 x half> [[VECINIT1]], half [[TMP0]], i32 2 // CHECK: [[VECINIT3:%.*]] = insertelement <4 x half> [[VECINIT2]], half [[TMP0]], i32 3 @@ -7742,7 +7742,7 @@ float16x4_t test_vmov_n_f16(float16_t *a) { } // CHECK-LABEL: @test_vmov_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %a, i32 1 // CHECK: ret <2 x float> [[VECINIT1_I]] float32x2_t test_vmov_n_f32(float32_t a) { @@ -7750,7 +7750,7 @@ float32x2_t test_vmov_n_f32(float32_t a) { } // CHECK-LABEL: @test_vmovq_n_u8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -7772,7 +7772,7 @@ uint8x16_t test_vmovq_n_u8(uint8_t a) { } // CHECK-LABEL: @test_vmovq_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -7786,7 +7786,7 @@ uint16x8_t test_vmovq_n_u16(uint16_t a) { } // CHECK-LABEL: @test_vmovq_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %a, i32 3 @@ -7796,7 +7796,7 @@ uint32x4_t test_vmovq_n_u32(uint32_t a) { } // CHECK-LABEL: @test_vmovq_n_s8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -7818,7 +7818,7 @@ int8x16_t test_vmovq_n_s8(int8_t a) { } // CHECK-LABEL: @test_vmovq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -7832,7 +7832,7 @@ int16x8_t test_vmovq_n_s16(int16_t a) { } // CHECK-LABEL: @test_vmovq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %a, i32 3 @@ -7842,7 +7842,7 @@ int32x4_t test_vmovq_n_s32(int32_t a) { } // CHECK-LABEL: @test_vmovq_n_p8( -// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 %a, i32 3 @@ -7864,7 +7864,7 @@ poly8x16_t test_vmovq_n_p8(poly8_t a) { } // CHECK-LABEL: @test_vmovq_n_p16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %a, i32 3 @@ -7879,7 +7879,7 @@ poly16x8_t test_vmovq_n_p16(poly16_t a) { // CHECK-LABEL: @test_vmovq_n_f16( // CHECK: [[TMP0:%.*]] = load half, ptr %a, align 2 -// CHECK: [[VECINIT:%.*]] = insertelement <8 x half> undef, half [[TMP0]], i32 0 +// CHECK: [[VECINIT:%.*]] = insertelement <8 x half> poison, half [[TMP0]], i32 0 // CHECK: [[VECINIT1:%.*]] = insertelement <8 x half> [[VECINIT]], half [[TMP0]], i32 1 // CHECK: [[VECINIT2:%.*]] = insertelement <8 x half> [[VECINIT1]], half [[TMP0]], i32 2 // CHECK: [[VECINIT3:%.*]] = insertelement <8 x half> [[VECINIT2]], half [[TMP0]], i32 3 @@ -7893,7 +7893,7 @@ float16x8_t test_vmovq_n_f16(float16_t *a) { } // CHECK-LABEL: @test_vmovq_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %a, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %a, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %a, i32 3 @@ -7903,7 +7903,7 @@ float32x4_t test_vmovq_n_f32(float32_t a) { } // CHECK-LABEL: @test_vmov_n_s64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> poison, i64 %a, i32 0 // CHECK: [[ADD_I:%.*]] = add <1 x i64> [[VECINIT_I]], [[VECINIT_I]] // CHECK: ret <1 x i64> [[ADD_I]] int64x1_t test_vmov_n_s64(int64_t a) { @@ -7912,7 +7912,7 @@ int64x1_t test_vmov_n_s64(int64_t a) { } // CHECK-LABEL: @test_vmov_n_u64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <1 x i64> poison, i64 %a, i32 0 // CHECK: [[ADD_I:%.*]] = add <1 x i64> [[VECINIT_I]], [[VECINIT_I]] // CHECK: ret <1 x i64> [[ADD_I]] uint64x1_t test_vmov_n_u64(uint64_t a) { @@ -7921,7 +7921,7 @@ uint64x1_t test_vmov_n_u64(uint64_t a) { } // CHECK-LABEL: @test_vmovq_n_s64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1 // CHECK: ret <2 x i64> [[VECINIT1_I]] int64x2_t test_vmovq_n_s64(int64_t a) { @@ -7929,7 +7929,7 @@ int64x2_t test_vmovq_n_s64(int64_t a) { } // CHECK-LABEL: @test_vmovq_n_u64( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 %a, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 %a, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 %a, i32 1 // CHECK: ret <2 x i64> [[VECINIT1_I]] uint64x2_t test_vmovq_n_u64(uint64_t a) { @@ -8140,7 +8140,7 @@ uint64x2_t test_vmull_lane_u32(uint32x2_t a, uint32x2_t b) { } // CHECK-LABEL: @test_vmull_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -8153,7 +8153,7 @@ int32x4_t test_vmull_n_s16(int16x4_t a, int16_t b) { } // CHECK-LABEL: @test_vmull_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %a to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -8164,7 +8164,7 @@ int64x2_t test_vmull_n_s32(int32x2_t a, int32_t b) { } // CHECK-LABEL: @test_vmull_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -8177,7 +8177,7 @@ uint32x4_t test_vmull_n_u16(uint16x4_t a, uint16_t b) { } // CHECK-LABEL: @test_vmull_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %a to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -8302,7 +8302,7 @@ uint32x4_t test_vmulq_lane_u32(uint32x4_t a, uint32x2_t b) { } // CHECK-LABEL: @test_vmul_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -8313,7 +8313,7 @@ int16x4_t test_vmul_n_s16(int16x4_t a, int16_t b) { } // CHECK-LABEL: @test_vmul_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[MUL_I:%.*]] = mul <2 x i32> %a, [[VECINIT1_I]] // CHECK: ret <2 x i32> [[MUL_I]] @@ -8322,7 +8322,7 @@ int32x2_t test_vmul_n_s32(int32x2_t a, int32_t b) { } // CHECK-LABEL: @test_vmul_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> poison, float %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %b, i32 1 // CHECK: [[MUL_I:%.*]] = fmul <2 x float> %a, [[VECINIT1_I]] // CHECK: ret <2 x float> [[MUL_I]] @@ -8331,7 +8331,7 @@ float32x2_t test_vmul_n_f32(float32x2_t a, float32_t b) { } // CHECK-LABEL: @test_vmul_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -8342,7 +8342,7 @@ uint16x4_t test_vmul_n_u16(uint16x4_t a, uint16_t b) { } // CHECK-LABEL: @test_vmul_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[MUL_I:%.*]] = mul <2 x i32> %a, [[VECINIT1_I]] // CHECK: ret <2 x i32> [[MUL_I]] @@ -8351,7 +8351,7 @@ uint32x2_t test_vmul_n_u32(uint32x2_t a, uint32_t b) { } // CHECK-LABEL: @test_vmulq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -8366,7 +8366,7 @@ int16x8_t test_vmulq_n_s16(int16x8_t a, int16_t b) { } // CHECK-LABEL: @test_vmulq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %b, i32 3 @@ -8377,7 +8377,7 @@ int32x4_t test_vmulq_n_s32(int32x4_t a, int32_t b) { } // CHECK-LABEL: @test_vmulq_n_f32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %b, i32 3 @@ -8388,7 +8388,7 @@ float32x4_t test_vmulq_n_f32(float32x4_t a, float32_t b) { } // CHECK-LABEL: @test_vmulq_n_u16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -8403,7 +8403,7 @@ uint16x8_t test_vmulq_n_u16(uint16x8_t a, uint16_t b) { } // CHECK-LABEL: @test_vmulq_n_u32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %b, i32 3 @@ -9444,7 +9444,7 @@ int64x2_t test_vqdmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) { } // CHECK-LABEL: @test_vqdmlal_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -9459,7 +9459,7 @@ int32x4_t test_vqdmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) { } // CHECK-LABEL: @test_vqdmlal_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> %b to <8 x i8> @@ -9522,7 +9522,7 @@ int64x2_t test_vqdmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) { } // CHECK-LABEL: @test_vqdmlsl_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %c, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %c, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %c, i32 3 @@ -9537,7 +9537,7 @@ int32x4_t test_vqdmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) { } // CHECK-LABEL: @test_vqdmlsl_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %c, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %c, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %c, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i64> %a to <16 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> %b to <8 x i8> @@ -9642,7 +9642,7 @@ int32x4_t test_vqdmulhq_lane_s32(int32x4_t a, int32x2_t b) { } // CHECK-LABEL: @test_vqdmulh_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -9656,7 +9656,7 @@ int16x4_t test_vqdmulh_n_s16(int16x4_t a, int16_t b) { } // CHECK-LABEL: @test_vqdmulh_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %a to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -9668,7 +9668,7 @@ int32x2_t test_vqdmulh_n_s32(int32x2_t a, int32_t b) { } // CHECK-LABEL: @test_vqdmulhq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -9686,7 +9686,7 @@ int16x8_t test_vqdmulhq_n_s16(int16x8_t a, int16_t b) { } // CHECK-LABEL: @test_vqdmulhq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %b, i32 3 @@ -9746,7 +9746,7 @@ int64x2_t test_vqdmull_lane_s32(int32x2_t a, int32x2_t b) { } // CHECK-LABEL: @test_vqdmull_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -9760,7 +9760,7 @@ int32x4_t test_vqdmull_n_s16(int16x4_t a, int16_t b) { } // CHECK-LABEL: @test_vqdmull_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %a to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -9992,7 +9992,7 @@ int32x4_t test_vqrdmulhq_lane_s32(int32x4_t a, int32x2_t b) { } // CHECK-LABEL: @test_vqrdmulh_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -10006,7 +10006,7 @@ int16x4_t test_vqrdmulh_n_s16(int16x4_t a, int16_t b) { } // CHECK-LABEL: @test_vqrdmulh_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[TMP0:%.*]] = bitcast <2 x i32> %a to <8 x i8> // CHECK: [[TMP1:%.*]] = bitcast <2 x i32> [[VECINIT1_I]] to <8 x i8> @@ -10018,7 +10018,7 @@ int32x2_t test_vqrdmulh_n_s32(int32x2_t a, int32_t b) { } // CHECK-LABEL: @test_vqrdmulhq_n_s16( -// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 %b, i32 3 @@ -10036,7 +10036,7 @@ int16x8_t test_vqrdmulhq_n_s16(int16x8_t a, int16_t b) { } // CHECK-LABEL: @test_vqrdmulhq_n_s32( -// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 %b, i32 0 +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 // CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 %b, i32 1 // CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 %b, i32 2 // CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 %b, i32 3 diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c deleted file mode 100644 index 97226a24f5d62fe1e1385ac882ba35b1c872301c..0000000000000000000000000000000000000000 --- a/clang/test/CodeGen/attr-counted-by.c +++ /dev/null @@ -1,742 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3 -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DCOUNTED_BY -O2 -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITH-ATTR %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DCOUNTED_BY -O2 -Wall -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITH-ATTR %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITHOUT-ATTR %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITHOUT-ATTR %s - -#if !__has_attribute(counted_by) -#error "has attribute broken" -#endif - -#ifdef COUNTED_BY -#define __counted_by(member) __attribute__((__counted_by__(member))) -#else -#define __counted_by(member) -#endif - -#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ - struct { \ - struct { } __empty_ ## NAME; \ - TYPE NAME[]; \ - } - -#define DECLARE_BOUNDED_FLEX_ARRAY(COUNT_TYPE, COUNT, TYPE, NAME) \ - struct { \ - COUNT_TYPE COUNT; \ - TYPE NAME[] __counted_by(COUNT); \ - } - -#define DECLARE_FLEX_ARRAY_COUNTED_BY(TYPE, NAME, COUNTED_BY) \ - struct { \ - struct { } __empty_ ## NAME; \ - TYPE NAME[] __counted_by(COUNTED_BY); \ - } - -typedef long unsigned int size_t; - -struct annotated { - unsigned long flags; - int count; - int array[] __counted_by(count); -}; - -struct union_of_fams { - unsigned long flags; - union { - /* count member type intentionally mismatched to induce padding */ - DECLARE_BOUNDED_FLEX_ARRAY(int, count_bytes, unsigned char, bytes); - DECLARE_BOUNDED_FLEX_ARRAY(unsigned char, count_ints, unsigned char, ints); - DECLARE_FLEX_ARRAY(unsigned char, unsafe); - }; -}; - -struct anon_struct { - unsigned long flags; - size_t count; - DECLARE_FLEX_ARRAY_COUNTED_BY(int, array, count); -}; - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP4]]) #[[ATTR4:[0-9]+]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont7: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test1(struct annotated *p, int index, int val) { - p->array[index] = val; -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], [[INDEX]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT12:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont12: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP0]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i32 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP3]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[NARROW]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i32 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP0]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP1]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[NARROW]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test2( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test2( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test2(struct annotated *p, size_t index) { - p->array[index] = __builtin_dynamic_object_size(p->array, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], [[INDEX]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT12:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[INDEX]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont12: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP0]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i32 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP3]], i32 4) -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = add nuw i32 [[TMP4]], 12 -// SANITIZE-WITH-ATTR-NEXT: [[NARROW15:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[NARROW]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[NARROW15]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i32 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 4) -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = add nuw i32 [[TMP2]], 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP0]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW2:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[NARROW]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[NARROW2]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test3( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test3( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[INDEX]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test3(struct annotated *p, size_t index) { - // This test differs from 'test2' by checking bdos on the whole array and not - // just the FAM. - p->array[index] = __builtin_dynamic_object_size(p, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label [[CONT13:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP4]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont13: -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = shl i32 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 244 -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV3:%.*]] = select i1 [[TMP5]], i32 [[TMP8]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV3]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sext i32 [[ADD]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP10]], [[TMP11]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP12]], label [[CONT34:%.*]], label [[HANDLER_OUT_OF_BOUNDS29:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds29: -// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = zext i32 [[ADD]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[TMP13]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont34: -// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp sgt i32 [[TMP9]], 3 -// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = shl i32 [[TMP9]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = add i32 [[TMP15]], 240 -// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = and i32 [[TMP16]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV20:%.*]] = select i1 [[TMP14]], i32 [[TMP17]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[TMP10]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV20]], ptr [[ARRAYIDX32]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[ADD45:%.*]] = add nsw i32 [[INDEX]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = sext i32 [[ADD45]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = zext i32 [[TMP18]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = icmp ult i64 [[TMP19]], [[TMP20]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP21]], label [[CONT56:%.*]], label [[HANDLER_OUT_OF_BOUNDS51:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds51: -// SANITIZE-WITH-ATTR-NEXT: [[TMP22:%.*]] = zext i32 [[ADD45]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[TMP22]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont56: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX54:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[TMP19]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP23:%.*]] = sub nsw i32 [[TMP18]], [[FAM_IDX]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP24:%.*]] = or i32 [[TMP23]], [[FAM_IDX]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP24]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP25:%.*]] = shl i32 [[TMP23]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP26:%.*]] = and i32 [[TMP25]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV41:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP26]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV41]], ptr [[ARRAYIDX54]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = shl i32 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = add i32 [[TMP2]], 244 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP1]], i32 [[TMP4]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP5]], 3 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = shl i32 [[TMP5]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i32 [[TMP7]], 240 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV4:%.*]] = select i1 [[TMP6]], i32 [[TMP9]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM6:%.*]] = sext i32 [[ADD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM6]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV4]], ptr [[ARRAYIDX7]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = sub nsw i32 [[TMP10]], [[FAM_IDX]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = or i32 [[TMP11]], [[FAM_IDX]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP12]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = shl i32 [[TMP11]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = and i32 [[TMP13]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV10:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP14]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD12:%.*]] = add nsw i32 [[INDEX]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM13:%.*]] = sext i32 [[ADD12]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM13]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV10]], ptr [[ARRAYIDX14]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test4( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX5]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM17:%.*]] = sext i32 [[ADD]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM17]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD31:%.*]] = add nsw i32 [[INDEX]], 2 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM32:%.*]] = sext i32 [[ADD31]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM32]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX33]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test4( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX3]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM9:%.*]] = sext i32 [[ADD]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM9]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX10]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD17:%.*]] = add nsw i32 [[INDEX]], 2 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM18:%.*]] = sext i32 [[ADD17]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM18]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX19]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test4(struct annotated *p, int index, int fam_idx) { - // This tests calculating the size from a pointer inside the FAM. - p->array[index] = (unsigned char)__builtin_dynamic_object_size(&p->array[3], 1); - p->array[index + 1] = (unsigned char)__builtin_dynamic_object_size(&(p->array[4]), 1); - p->array[index + 2] = (unsigned char)__builtin_dynamic_object_size(&(p->array[fam_idx]), 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test5( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i64, ptr [[COUNT]], align 8, !tbaa [[TBAA8:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP0]], [[TMP1]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT12:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP3]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont12: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT]], ptr [[P]], i64 1 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl nuw i64 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i64 @llvm.umax.i64(i64 [[TMP4]], i64 16) -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[TMP0]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP6]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test5( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i64, ptr [[COUNT]], align 8, !tbaa [[TBAA6:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.umax.i64(i64 [[TMP1]], i64 16) -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[TMP0]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP3]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT]], ptr [[P]], i64 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test5( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 1 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test5( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 1 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test5(struct anon_struct *p, int index) { - p->array[index] = __builtin_dynamic_object_size(p, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i64, ptr [[COUNT]], align 8, !tbaa [[TBAA8]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP0]], [[TMP1]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT12:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[TMP3]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont12: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT]], ptr [[P]], i64 1 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[TMP0]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP0]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl i32 [[DOTTR]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP4]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i64, ptr [[COUNT]], align 8, !tbaa [[TBAA6]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[TMP0]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP0]] to i32 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i32 [[DOTTR]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP1]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT]], ptr [[P]], i64 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test6( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 1 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test6( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[P]], i64 1 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test6(struct anon_struct *p, int index) { - p->array[index] = __builtin_dynamic_object_size(p->array, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 8 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 255 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[TMP2]], [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label [[CONT23:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[TMP4]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont23: -// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[TMP5]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP1]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 12) -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = trunc i32 [[TMP6]] to i8 -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i8 [[TMP7]], 4 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP8]] -// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA10:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 8, !tbaa [[TBAA8:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 12) -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP1]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i8 [[TMP3]], 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP4]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test7( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6:![0-9]+]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test7( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6:![0-9]+]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test7(struct union_of_fams *p, int index) { - p->ints[index] = __builtin_dynamic_object_size(p, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], [[TMP2]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT24:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP5]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont24: -// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[TMP3]] -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = tail call i8 @llvm.smax.i8(i8 [[TMP1]], i8 0) -// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA10]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 8, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i8 @llvm.smax.i8(i8 [[TMP1]], i8 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[NARROW]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test8( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test8( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test8(struct union_of_fams *p, int index) { - p->ints[index] = __builtin_dynamic_object_size(p->ints, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP2]], [[TMP3]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT24:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB14:[0-9]+]], i64 [[TMP5]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont24: -// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[TMP2]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP1]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 12) -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = trunc i32 [[TMP6]] to i8 -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i8 [[TMP7]], 4 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP8]] -// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA10]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 8, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 12) -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[TMP1]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i8 [[TMP3]], 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP4]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test9( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test9( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test9(struct union_of_fams *p, int index) { - p->bytes[index] = (unsigned char)__builtin_dynamic_object_size(p, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP2]], [[TMP3]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT24:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP5]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont24: -// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[TMP2]] -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0) -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA10]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[P]], i64 0, i32 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 8, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test10( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test10( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test10(struct union_of_fams *p, int index) { - p->bytes[index] = (unsigned char)__builtin_dynamic_object_size(p->bytes, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test11( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[COUNT]], align 8, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF7]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[TMP4]]) #[[ATTR4]], !nosanitize [[META6]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]] -// SANITIZE-WITH-ATTR: cont7: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[P]], i64 0, i32 2, i64 [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test11( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test11( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test11( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[P]], i64 0, i32 2, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test11(struct annotated *p, int index) { - p->array[index] = __builtin_dynamic_object_size(&p->count, 1); -} diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c index 9150597e8c5a8470f8f79d68bb8603495c6c1a48..2c3e6931800cd883f19b168a2a23327bec4c3e34 100644 --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX +// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX // RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WINDOWS #ifdef _WIN64 diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c index 4f8fe13530fdb7b3c552c4eafd51e18dd2f1302b..2ad41edf20dfa01b0d42bd1419758b206e255eb0 100644 --- a/clang/test/CodeGen/attr-ifunc.c +++ b/clang/test/CodeGen/attr-ifunc.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify %s // RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only -DCHECK_ALIASES %s // RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsyntax-only -verify -emit-llvm-only %s #if defined(_WIN32) void foo(void) {} @@ -36,6 +37,25 @@ void *f6_resolver(void) __attribute__((ifunc("f6_resolver_resolver"))); void f6(void) __attribute__((ifunc("f6_resolver"))); // expected-error@-1 {{ifunc must point to a defined function}} +#elif defined(__APPLE__) + +// NOTE: aliases are not supported on Darwin, so the above tests are not relevant. + +#define STR2(X) #X +#define STR(X) STR2(X) +#define PREFIX STR(__USER_LABEL_PREFIX__) + +void f1a(void) __asm("f1"); +void f1a(void) {} +// expected-note@-1 {{previous definition is here}} +void f1(void) __attribute__((ifunc(PREFIX "f1_ifunc"))) __asm("f1"); +// expected-error@-1 {{definition with same mangled name 'f1' as another definition}} +void *f1_ifunc(void) { return 0; } + +void *f6_ifunc(int i); +void __attribute__((ifunc(PREFIX "f6_ifunc"))) f6(void) {} +// expected-error@-1 {{definition 'f6' cannot also be an ifunc}} + #else void f1a(void) __asm("f1"); void f1a(void) {} diff --git a/clang/test/CodeGen/attr-ifunc.cpp b/clang/test/CodeGen/attr-ifunc.cpp index 5b5b2c14b4074b7406f1418b25b8fa4a9d171c9f..b6e342df46eb583bdcd66a2794f3e2b3f7c020e3 100644 --- a/clang/test/CodeGen/attr-ifunc.cpp +++ b/clang/test/CodeGen/attr-ifunc.cpp @@ -1,5 +1,9 @@ // RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsyntax-only -verify -emit-llvm-only %s +// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify -emit-llvm-only %s // RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -triple x86_64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -triple arm64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s void *f1_ifunc(void) { return nullptr; } void f1(void) __attribute__((ifunc("f1_ifunc"))); diff --git a/clang/test/CodeGen/attr-riscv-rvv-vector-bits-globals.c b/clang/test/CodeGen/attr-riscv-rvv-vector-bits-globals.c index 447c3803dec8e3651f7b13b3e1056d5ec66e827d..8bdcd9af20efcad8d8cede6142a75150cc4dfbe9 100644 --- a/clang/test/CodeGen/attr-riscv-rvv-vector-bits-globals.c +++ b/clang/test/CodeGen/attr-riscv-rvv-vector-bits-globals.c @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=1 -mvscale-max=1 -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128 -// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=4 -mvscale-max=4 -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-512 +// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=1 -mvscale-max=1 -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-64 +// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +f -target-feature +d -target-feature +zve64d -mvscale-min=4 -mvscale-max=4 -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-256 // REQUIRES: riscv-registered-target @@ -25,17 +25,17 @@ fixed_int64m1_t global_i64; // WRITES //===----------------------------------------------------------------------===// -// CHECK-128-LABEL: @write_global_i64( -// CHECK-128-NEXT: entry: -// CHECK-128-NEXT: [[CASTFIXEDSVE:%.*]] = tail call <1 x i64> @llvm.vector.extract.v1i64.nxv1i64( [[V:%.*]], i64 0) -// CHECK-128-NEXT: store <1 x i64> [[CASTFIXEDSVE]], ptr @global_i64, align 8, !tbaa [[TBAA4:![0-9]+]] -// CHECK-128-NEXT: ret void +// CHECK-64-LABEL: @write_global_i64( +// CHECK-64-NEXT: entry: +// CHECK-64-NEXT: [[CAST_FIXED:%.*]] = tail call <1 x i64> @llvm.vector.extract.v1i64.nxv1i64( [[V:%.*]], i64 0) +// CHECK-64-NEXT: store <1 x i64> [[CAST_FIXED]], ptr @global_i64, align 8, !tbaa [[TBAA4:![0-9]+]] +// CHECK-64-NEXT: ret void // -// CHECK-512-LABEL: @write_global_i64( -// CHECK-512-NEXT: entry: -// CHECK-512-NEXT: [[CASTFIXEDSVE:%.*]] = tail call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64( [[V:%.*]], i64 0) -// CHECK-512-NEXT: store <4 x i64> [[CASTFIXEDSVE]], ptr @global_i64, align 8, !tbaa [[TBAA4:![0-9]+]] -// CHECK-512-NEXT: ret void +// CHECK-256-LABEL: @write_global_i64( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[CAST_FIXED:%.*]] = tail call <4 x i64> @llvm.vector.extract.v4i64.nxv1i64( [[V:%.*]], i64 0) +// CHECK-256-NEXT: store <4 x i64> [[CAST_FIXED]], ptr @global_i64, align 8, !tbaa [[TBAA4:![0-9]+]] +// CHECK-256-NEXT: ret void // void write_global_i64(vint64m1_t v) { global_i64 = v; } @@ -43,16 +43,16 @@ void write_global_i64(vint64m1_t v) { global_i64 = v; } // READS //===----------------------------------------------------------------------===// -// CHECK-128-LABEL: @read_global_i64( -// CHECK-128-NEXT: entry: -// CHECK-128-NEXT: [[TMP0:%.*]] = load <1 x i64>, ptr @global_i64, align 8, !tbaa [[TBAA4]] -// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v1i64( undef, <1 x i64> [[TMP0]], i64 0) -// CHECK-128-NEXT: ret [[CASTSCALABLESVE]] +// CHECK-64-LABEL: @read_global_i64( +// CHECK-64-NEXT: entry: +// CHECK-64-NEXT: [[TMP0:%.*]] = load <1 x i64>, ptr @global_i64, align 8, !tbaa [[TBAA4]] +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v1i64( undef, <1 x i64> [[TMP0]], i64 0) +// CHECK-64-NEXT: ret [[CAST_SCALABLE]] // -// CHECK-512-LABEL: @read_global_i64( -// CHECK-512-NEXT: entry: -// CHECK-512-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr @global_i64, align 8, !tbaa [[TBAA4]] -// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v4i64( undef, <4 x i64> [[TMP0]], i64 0) -// CHECK-512-NEXT: ret [[CASTSCALABLESVE]] +// CHECK-256-LABEL: @read_global_i64( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr @global_i64, align 8, !tbaa [[TBAA4]] +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v4i64( undef, <4 x i64> [[TMP0]], i64 0) +// CHECK-256-NEXT: ret [[CAST_SCALABLE]] // vint64m1_t read_global_i64() { return global_i64; } diff --git a/clang/test/CodeGen/attr-target-clones.c b/clang/test/CodeGen/attr-target-clones.c index 4b99914031b10e557cbccd02abf228096cae95d7..3256db061f9a22b18439d0884e32a9c36aea2ae8 100644 --- a/clang/test/CodeGen/attr-target-clones.c +++ b/clang/test/CodeGen/attr-target-clones.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=LINUX,CHECK +// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=DARWIN,CHECK // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefixes=WINDOWS,CHECK // LINUX: $foo.resolver = comdat any @@ -7,6 +8,8 @@ // LINUX: $foo_inline.resolver = comdat any // LINUX: $foo_inline2.resolver = comdat any +// DARWIN-NOT: comdat any + // WINDOWS: $foo = comdat any // WINDOWS: $foo_dupes = comdat any // WINDOWS: $unused = comdat any @@ -16,6 +19,9 @@ // LINUX: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] } // LINUX: @__cpu_features2 = external dso_local global [3 x i32] +// DARWIN: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] } +// DARWIN: @__cpu_features2 = external dso_local global [3 x i32] + // LINUX: @internal.ifunc = internal alias i32 (), ptr @internal // LINUX: @foo.ifunc = weak_odr alias i32 (), ptr @foo // LINUX: @foo_dupes.ifunc = weak_odr alias void (), ptr @foo_dupes @@ -34,10 +40,12 @@ // LINUX: @foo_used_no_defn = weak_odr ifunc i32 (), ptr @foo_used_no_defn.resolver // LINUX: @isa_level = weak_odr ifunc i32 (i32), ptr @isa_level.resolver + static int __attribute__((target_clones("sse4.2, default"))) internal(void) { return 0; } int use(void) { return internal(); } /// Internal linkage resolvers do not use comdat. // LINUX: define internal ptr @internal.resolver() { +// DARWIN: define internal ptr @internal.resolver() { // WINDOWS: define internal i32 @internal() { int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; } @@ -47,6 +55,12 @@ int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; } // LINUX: ret ptr @foo.sse4.2.0 // LINUX: ret ptr @foo.default.1 +// DARWIN: define {{.*}}i32 @foo.sse4.2.0() +// DARWIN: define {{.*}}i32 @foo.default.1() +// DARWIN: define weak_odr ptr @foo.resolver() { +// DARWIN: ret ptr @foo.sse4.2.0 +// DARWIN: ret ptr @foo.default.1 + // WINDOWS: define dso_local i32 @foo.sse4.2.0() // WINDOWS: define dso_local i32 @foo.default.1() // WINDOWS: define weak_odr dso_local i32 @foo() comdat @@ -60,6 +74,12 @@ __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) { // LINUX: ret ptr @foo_dupes.sse4.2.0 // LINUX: ret ptr @foo_dupes.default.1 +// DARWIN: define {{.*}}void @foo_dupes.default.1() +// DARWIN: define {{.*}}void @foo_dupes.sse4.2.0() +// DARWIN: define weak_odr ptr @foo_dupes.resolver() { +// DARWIN: ret ptr @foo_dupes.sse4.2.0 +// DARWIN: ret ptr @foo_dupes.default.1 + // WINDOWS: define dso_local void @foo_dupes.default.1() // WINDOWS: define dso_local void @foo_dupes.sse4.2.0() // WINDOWS: define weak_odr dso_local void @foo_dupes() comdat @@ -68,17 +88,21 @@ __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) { void bar2(void) { // LINUX: define {{.*}}void @bar2() + // DARWIN: define {{.*}}void @bar2() // WINDOWS: define dso_local void @bar2() foo_dupes(); // LINUX: call void @foo_dupes() + // DARWIN: call void @foo_dupes() // WINDOWS: call void @foo_dupes() } int bar(void) { // LINUX: define {{.*}}i32 @bar() #[[DEF:[0-9]+]] + // DARWIN: define {{.*}}i32 @bar() #[[DEF:[0-9]+]] // WINDOWS: define dso_local i32 @bar() #[[DEF:[0-9]+]] return foo(); // LINUX: call i32 @foo() + // DARWIN: call i32 @foo() // WINDOWS: call i32 @foo() } @@ -89,6 +113,12 @@ void __attribute__((target_clones("default, arch=ivybridge"))) unused(void) {} // LINUX: ret ptr @unused.arch_ivybridge.0 // LINUX: ret ptr @unused.default.1 +// DARWIN: define {{.*}}void @unused.default.1() +// DARWIN: define {{.*}}void @unused.arch_ivybridge.0() +// DARWIN: define weak_odr ptr @unused.resolver() { +// DARWIN: ret ptr @unused.arch_ivybridge.0 +// DARWIN: ret ptr @unused.default.1 + // WINDOWS: define dso_local void @unused.default.1() // WINDOWS: define dso_local void @unused.arch_ivybridge.0() // WINDOWS: define weak_odr dso_local void @unused() comdat @@ -103,10 +133,13 @@ foo_inline2(void); int bar3(void) { // LINUX: define {{.*}}i32 @bar3() + // DARWIN: define {{.*}}i32 @bar3() // WINDOWS: define dso_local i32 @bar3() return foo_inline() + foo_inline2(); // LINUX: call i32 @foo_inline() // LINUX: call i32 @foo_inline2() + // DARWIN: call i32 @foo_inline() + // DARWIN: call i32 @foo_inline2() // WINDOWS: call i32 @foo_inline() // WINDOWS: call i32 @foo_inline2() } @@ -116,6 +149,11 @@ int bar3(void) { // LINUX: ret ptr @foo_inline.sse4.2.1 // LINUX: ret ptr @foo_inline.default.2 +// DARWIN: define weak_odr ptr @foo_inline.resolver() { +// DARWIN: ret ptr @foo_inline.arch_sandybridge.0 +// DARWIN: ret ptr @foo_inline.sse4.2.1 +// DARWIN: ret ptr @foo_inline.default.2 + // WINDOWS: define weak_odr dso_local i32 @foo_inline() comdat // WINDOWS: musttail call i32 @foo_inline.arch_sandybridge.0 // WINDOWS: musttail call i32 @foo_inline.sse4.2.1 @@ -128,6 +166,11 @@ foo_inline2(void){ return 0; } // LINUX: ret ptr @foo_inline2.sse4.2.1 // LINUX: ret ptr @foo_inline2.default.2 +// DARWIN: define weak_odr ptr @foo_inline2.resolver() { +// DARWIN: ret ptr @foo_inline2.arch_sandybridge.0 +// DARWIN: ret ptr @foo_inline2.sse4.2.1 +// DARWIN: ret ptr @foo_inline2.default.2 + // WINDOWS: define weak_odr dso_local i32 @foo_inline2() comdat // WINDOWS: musttail call i32 @foo_inline2.arch_sandybridge.0 // WINDOWS: musttail call i32 @foo_inline2.sse4.2.1 @@ -142,9 +185,11 @@ foo_used_no_defn(void); int test_foo_used_no_defn(void) { // LINUX: define {{.*}}i32 @test_foo_used_no_defn() + // DARWIN: define {{.*}}i32 @test_foo_used_no_defn() // WINDOWS: define dso_local i32 @test_foo_used_no_defn() return foo_used_no_defn(); // LINUX: call i32 @foo_used_no_defn() + // DARWIN: call i32 @foo_used_no_defn() // WINDOWS: call i32 @foo_used_no_defn() } @@ -153,6 +198,10 @@ int test_foo_used_no_defn(void) { // LINUX: ret ptr @foo_used_no_defn.sse4.2.0 // LINUX: ret ptr @foo_used_no_defn.default.1 +// DARWIN: define weak_odr ptr @foo_used_no_defn.resolver() { +// DARWIN: ret ptr @foo_used_no_defn.sse4.2.0 +// DARWIN: ret ptr @foo_used_no_defn.default.1 + // WINDOWS: define weak_odr dso_local i32 @foo_used_no_defn() comdat // WINDOWS: musttail call i32 @foo_used_no_defn.sse4.2.0 // WINDOWS: musttail call i32 @foo_used_no_defn.default.1 @@ -180,12 +229,37 @@ int isa_level(int) { return 0; } // LINUX: ret ptr @isa_level.arch_x86-64.0 // LINUX: ret ptr @isa_level.default.4 +// DARWIN: define{{.*}} i32 @isa_level.default.4( +// DARWIN: define{{.*}} i32 @isa_level.arch_x86-64.0( +// DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v2.1( +// DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v3.2( +// DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v4.3( +// DARWIN: define weak_odr ptr @isa_level.resolver() { +// DARWIN: call void @__cpu_indicator_init() +// DARWIN-NEXT: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) +// DARWIN-NEXT: and i32 %[[#]], 4 +// DARWIN: ret ptr @isa_level.arch_x86-64-v4.3 +// DARWIN: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) +// DARWIN-NEXT: and i32 %[[#]], 2 +// DARWIN: ret ptr @isa_level.arch_x86-64-v3.2 +// DARWIN: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) +// DARWIN-NEXT: and i32 %[[#]], 1 +// DARWIN: ret ptr @isa_level.arch_x86-64-v2.1 +// DARWIN: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 1) +// DARWIN-NEXT: and i32 %[[#]], -2147483648 +// DARWIN: ret ptr @isa_level.arch_x86-64.0 +// DARWIN: ret ptr @isa_level.default.4 + // Deferred emission of inline definitions. // LINUX: define linkonce i32 @foo_inline.arch_sandybridge.0() #[[SB:[0-9]+]] // LINUX: define linkonce i32 @foo_inline.default.2() #[[DEF:[0-9]+]] // LINUX: define linkonce i32 @foo_inline.sse4.2.1() #[[SSE42:[0-9]+]] +// DARWIN: define linkonce i32 @foo_inline.arch_sandybridge.0() #[[SB:[0-9]+]] +// DARWIN: define linkonce i32 @foo_inline.default.2() #[[DEF:[0-9]+]] +// DARWIN: define linkonce i32 @foo_inline.sse4.2.1() #[[SSE42:[0-9]+]] + // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_sandybridge.0() #[[SB:[0-9]+]] // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.default.2() #[[DEF]] // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.sse4.2.1() #[[SSE42:[0-9]+]] @@ -195,6 +269,10 @@ int isa_level(int) { return 0; } // LINUX: define linkonce i32 @foo_inline2.default.2() #[[DEF]] // LINUX: define linkonce i32 @foo_inline2.sse4.2.1() #[[SSE42]] +// DARWIN: define linkonce i32 @foo_inline2.arch_sandybridge.0() #[[SB]] +// DARWIN: define linkonce i32 @foo_inline2.default.2() #[[DEF]] +// DARWIN: define linkonce i32 @foo_inline2.sse4.2.1() #[[SSE42]] + // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.arch_sandybridge.0() #[[SB]] // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.default.2() #[[DEF]] // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.sse4.2.1() #[[SSE42]] @@ -203,6 +281,9 @@ int isa_level(int) { return 0; } // LINUX: declare i32 @foo_used_no_defn.default.1() // LINUX: declare i32 @foo_used_no_defn.sse4.2.0() +// DARWIN: declare i32 @foo_used_no_defn.default.1() +// DARWIN: declare i32 @foo_used_no_defn.sse4.2.0() + // WINDOWS: declare dso_local i32 @foo_used_no_defn.default.1() // WINDOWS: declare dso_local i32 @foo_used_no_defn.sse4.2.0() diff --git a/clang/test/CodeGen/attr-target-mv-func-ptrs.c b/clang/test/CodeGen/attr-target-mv-func-ptrs.c index b5f3a1b02f36f4f732652998d89ced4c2153135b..e07ad6a7c1067d74c1f3beebc3b59fb0826ef404 100644 --- a/clang/test/CodeGen/attr-target-mv-func-ptrs.c +++ b/clang/test/CodeGen/attr-target-mv-func-ptrs.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS int __attribute__((target("sse4.2"))) foo(int i) { return 0; } int __attribute__((target("arch=sandybridge"))) foo(int); diff --git a/clang/test/CodeGen/attr-target-mv-va-args.c b/clang/test/CodeGen/attr-target-mv-va-args.c index 96821c610235bdc6c2b70c29621ae7f009b853ac..dbf5a74205c4c19414ad01bb84510c645fc5bd4f 100644 --- a/clang/test/CodeGen/attr-target-mv-va-args.c +++ b/clang/test/CodeGen/attr-target-mv-va-args.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefixes=NO-IFUNC,WINDOWS // RUN: %clang_cc1 -triple x86_64-linux-musl -emit-llvm %s -o - | FileCheck %s --check-prefixes=NO-IFUNC,NO-IFUNC-ELF // RUN: %clang_cc1 -triple x86_64-fuchsia -emit-llvm %s -o - | FileCheck %s --check-prefixes=NO-IFUNC,NO-IFUNC-ELF +// RUN: %clang_cc1 -triple x86_64-apple-macho -emit-llvm %s -o - | FileCheck %s --check-prefix=IFUNC-MACHO int __attribute__((target("sse4.2"))) foo(int i, ...) { return 0; } int __attribute__((target("arch=sandybridge"))) foo(int i, ...); int __attribute__((target("arch=ivybridge"))) foo(int i, ...) {return 1;} @@ -30,6 +31,24 @@ int bar(void) { // IFUNC-ELF: ret ptr @foo // IFUNC-ELF: declare i32 @foo.arch_sandybridge(i32 noundef, ...) +// IFUNC-MACHO: @foo.ifunc = weak_odr ifunc i32 (i32, ...), ptr @foo.resolver +// IFUNC-MACHO: define{{.*}} i32 @foo.sse4.2(i32 noundef %i, ...) +// IFUNC-MACHO: ret i32 0 +// IFUNC-MACHO: define{{.*}} i32 @foo.arch_ivybridge(i32 noundef %i, ...) +// IFUNC-MACHO: ret i32 1 +// IFUNC-MACHO: define{{.*}} i32 @foo(i32 noundef %i, ...) +// IFUNC-MACHO: ret i32 2 +// IFUNC-MACHO: define{{.*}} i32 @bar() +// IFUNC-MACHO: call i32 (i32, ...) @foo.ifunc(i32 noundef 1, i32 noundef 97, double +// IFUNC-MACHO: call i32 (i32, ...) @foo.ifunc(i32 noundef 2, double noundef 2.2{{[0-9Ee+]+}}, ptr noundef + +// IFUNC-MACHO: define weak_odr ptr @foo.resolver() +// IFUNC-MACHO: ret ptr @foo.arch_sandybridge +// IFUNC-MACHO: ret ptr @foo.arch_ivybridge +// IFUNC-MACHO: ret ptr @foo.sse4.2 +// IFUNC-MACHO: ret ptr @foo +// IFUNC-MACHO: declare i32 @foo.arch_sandybridge(i32 noundef, ...) + // NO-IFUNC: define dso_local i32 @foo.sse4.2(i32 noundef %i, ...) // NO-IFUNC: ret i32 0 // NO-IFUNC: define dso_local i32 @foo.arch_ivybridge(i32 noundef %i, ...) diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c index bdf8c49de4ae869cc6053518a8f656fc8c222886..2c4b95ca04370a02fbc8be6f12833b77418fa7c1 100644 --- a/clang/test/CodeGen/attr-target-mv.c +++ b/clang/test/CodeGen/attr-target-mv.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX +// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS int __attribute__((target("sse4.2"))) foo(void) { return 0; } @@ -107,6 +108,8 @@ void calls_pr50025c(void) { pr50025c(); } // LINUX: $pr50025c.resolver = comdat any // LINUX: $pr50025b.resolver = comdat any +// DARWIN-NOT: comdat + // WINDOWS: $foo.resolver = comdat any // WINDOWS: $foo_inline.resolver = comdat any // WINDOWS: $foo_decls.resolver = comdat any @@ -133,73 +136,74 @@ void calls_pr50025c(void) { pr50025c(); } // LINUX: @llvm.compiler.used = appending global [2 x ptr] [ptr @foo_used, ptr @foo_used2.avx_sse4.2], section "llvm.metadata" +// DARWIN: @llvm.used = appending global [2 x ptr] [ptr @foo_used, ptr @foo_used2.avx_sse4.2], section "llvm.metadata" // WINDOWS: @llvm.used = appending global [2 x ptr] [ptr @foo_used, ptr @foo_used2.avx_sse4.2], section "llvm.metadata" -// LINUX: @foo.ifunc = weak_odr ifunc i32 (), ptr @foo.resolver -// LINUX: @foo_internal.ifunc = internal ifunc i32 (), ptr @foo_internal.resolver -// LINUX: @foo_inline.ifunc = weak_odr ifunc i32 (), ptr @foo_inline.resolver -// LINUX: @foo_decls.ifunc = weak_odr ifunc void (), ptr @foo_decls.resolver -// LINUX: @foo_multi.ifunc = weak_odr ifunc void (i32, double), ptr @foo_multi.resolver -// LINUX: @fwd_decl_default.ifunc = weak_odr ifunc i32 (), ptr @fwd_decl_default.resolver -// LINUX: @fwd_decl_avx.ifunc = weak_odr ifunc i32 (), ptr @fwd_decl_avx.resolver - -// LINUX: define{{.*}} i32 @foo.sse4.2() -// LINUX: ret i32 0 -// LINUX: define{{.*}} i32 @foo.arch_ivybridge() -// LINUX: ret i32 1 -// LINUX: define{{.*}} i32 @foo.arch_goldmont() -// LINUX: ret i32 3 -// LINUX: define{{.*}} i32 @foo.arch_goldmont-plus() -// LINUX: ret i32 4 -// LINUX: define{{.*}} i32 @foo.arch_tremont() -// LINUX: ret i32 5 -// LINUX: define{{.*}} i32 @foo.arch_icelake-client() -// LINUX: ret i32 6 -// LINUX: define{{.*}} i32 @foo.arch_icelake-server() -// LINUX: ret i32 7 -// LINUX: define{{.*}} i32 @foo.arch_cooperlake() -// LINUX: ret i32 8 -// LINUX: define{{.*}} i32 @foo.arch_tigerlake() -// LINUX: ret i32 9 -// LINUX: define{{.*}} i32 @foo.arch_sapphirerapids() -// LINUX: ret i32 10 -// LINUX: define{{.*}} i32 @foo.arch_alderlake() -// LINUX: ret i32 11 -// LINUX: define{{.*}} i32 @foo.arch_rocketlake() -// LINUX: ret i32 12 -// LINUX: define{{.*}} i32 @foo.arch_core2() -// LINUX: ret i32 13 -// LINUX: define{{.*}} i32 @foo.arch_raptorlake() -// LINUX: ret i32 14 -// LINUX: define{{.*}} i32 @foo.arch_meteorlake() -// LINUX: ret i32 15 -// LINUX: define{{.*}} i32 @foo.arch_sierraforest() -// LINUX: ret i32 16 -// LINUX: define{{.*}} i32 @foo.arch_grandridge() -// LINUX: ret i32 17 -// LINUX: define{{.*}} i32 @foo.arch_graniterapids() -// LINUX: ret i32 18 -// LINUX: define{{.*}} i32 @foo.arch_emeraldrapids() -// LINUX: ret i32 19 -// LINUX: define{{.*}} i32 @foo.arch_graniterapids-d() -// LINUX: ret i32 20 -// LINUX: define{{.*}} i32 @foo.arch_arrowlake() -// LINUX: ret i32 21 -// LINUX: define{{.*}} i32 @foo.arch_arrowlake-s() -// LINUX: ret i32 22 -// LINUX: define{{.*}} i32 @foo.arch_lunarlake() -// LINUX: ret i32 23 -// LINUX: define{{.*}} i32 @foo.arch_gracemont() -// LINUX: ret i32 24 -// LINUX: define{{.*}} i32 @foo.arch_pantherlake() -// LINUX: ret i32 25 -// LINUX: define{{.*}} i32 @foo.arch_clearwaterforest() -// LINUX: ret i32 26 -// LINUX: define{{.*}} i32 @foo() -// LINUX: ret i32 2 -// LINUX: define{{.*}} i32 @bar() -// LINUX: call i32 @foo.ifunc() +// ITANIUM: @foo.ifunc = weak_odr ifunc i32 (), ptr @foo.resolver +// ITANIUM: @foo_internal.ifunc = internal ifunc i32 (), ptr @foo_internal.resolver +// ITANIUM: @foo_inline.ifunc = weak_odr ifunc i32 (), ptr @foo_inline.resolver +// ITANIUM: @foo_decls.ifunc = weak_odr ifunc void (), ptr @foo_decls.resolver +// ITANIUM: @foo_multi.ifunc = weak_odr ifunc void (i32, double), ptr @foo_multi.resolver +// ITANIUM: @fwd_decl_default.ifunc = weak_odr ifunc i32 (), ptr @fwd_decl_default.resolver +// ITANIUM: @fwd_decl_avx.ifunc = weak_odr ifunc i32 (), ptr @fwd_decl_avx.resolver + +// ITANIUM: define{{.*}} i32 @foo.sse4.2() +// ITANIUM: ret i32 0 +// ITANIUM: define{{.*}} i32 @foo.arch_ivybridge() +// ITANIUM: ret i32 1 +// ITANIUM: define{{.*}} i32 @foo.arch_goldmont() +// ITANIUM: ret i32 3 +// ITANIUM: define{{.*}} i32 @foo.arch_goldmont-plus() +// ITANIUM: ret i32 4 +// ITANIUM: define{{.*}} i32 @foo.arch_tremont() +// ITANIUM: ret i32 5 +// ITANIUM: define{{.*}} i32 @foo.arch_icelake-client() +// ITANIUM: ret i32 6 +// ITANIUM: define{{.*}} i32 @foo.arch_icelake-server() +// ITANIUM: ret i32 7 +// ITANIUM: define{{.*}} i32 @foo.arch_cooperlake() +// ITANIUM: ret i32 8 +// ITANIUM: define{{.*}} i32 @foo.arch_tigerlake() +// ITANIUM: ret i32 9 +// ITANIUM: define{{.*}} i32 @foo.arch_sapphirerapids() +// ITANIUM: ret i32 10 +// ITANIUM: define{{.*}} i32 @foo.arch_alderlake() +// ITANIUM: ret i32 11 +// ITANIUM: define{{.*}} i32 @foo.arch_rocketlake() +// ITANIUM: ret i32 12 +// ITANIUM: define{{.*}} i32 @foo.arch_core2() +// ITANIUM: ret i32 13 +// ITANIUM: define{{.*}} i32 @foo.arch_raptorlake() +// ITANIUM: ret i32 14 +// ITANIUM: define{{.*}} i32 @foo.arch_meteorlake() +// ITANIUM: ret i32 15 +// ITANIUM: define{{.*}} i32 @foo.arch_sierraforest() +// ITANIUM: ret i32 16 +// ITANIUM: define{{.*}} i32 @foo.arch_grandridge() +// ITANIUM: ret i32 17 +// ITANIUM: define{{.*}} i32 @foo.arch_graniterapids() +// ITANIUM: ret i32 18 +// ITANIUM: define{{.*}} i32 @foo.arch_emeraldrapids() +// ITANIUM: ret i32 19 +// ITANIUM: define{{.*}} i32 @foo.arch_graniterapids-d() +// ITANIUM: ret i32 20 +// ITANIUM: define{{.*}} i32 @foo.arch_arrowlake() +// ITANIUM: ret i32 21 +// ITANIUM: define{{.*}} i32 @foo.arch_arrowlake-s() +// ITANIUM: ret i32 22 +// ITANIUM: define{{.*}} i32 @foo.arch_lunarlake() +// ITANIUM: ret i32 23 +// ITANIUM: define{{.*}} i32 @foo.arch_gracemont() +// ITANIUM: ret i32 24 +// ITANIUM: define{{.*}} i32 @foo.arch_pantherlake() +// ITANIUM: ret i32 25 +// ITANIUM: define{{.*}} i32 @foo.arch_clearwaterforest() +// ITANIUM: ret i32 26 +// ITANIUM: define{{.*}} i32 @foo() +// ITANIUM: ret i32 2 +// ITANIUM: define{{.*}} i32 @bar() +// ITANIUM: call i32 @foo.ifunc() // WINDOWS: define dso_local i32 @foo.sse4.2() // WINDOWS: ret i32 0 @@ -258,12 +262,13 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: define dso_local i32 @bar() // WINDOWS: call i32 @foo.resolver() -// LINUX: define weak_odr ptr @foo.resolver() comdat -// LINUX: call void @__cpu_indicator_init() -// LINUX: ret ptr @foo.arch_sandybridge -// LINUX: ret ptr @foo.arch_ivybridge -// LINUX: ret ptr @foo.sse4.2 -// LINUX: ret ptr @foo +// ITANIUM: define weak_odr ptr @foo.resolver() +// LINUX-SAME: comdat +// ITANIUM: call void @__cpu_indicator_init() +// ITANIUM: ret ptr @foo.arch_sandybridge +// ITANIUM: ret ptr @foo.arch_ivybridge +// ITANIUM: ret ptr @foo.sse4.2 +// ITANIUM: ret ptr @foo // WINDOWS: define weak_odr dso_local i32 @foo.resolver() comdat // WINDOWS: call void @__cpu_indicator_init() @@ -273,22 +278,23 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: call i32 @foo /// Internal linkage resolvers do not use comdat. -// LINUX: define internal ptr @foo_internal.resolver() { +// ITANIUM: define internal ptr @foo_internal.resolver() { // WINDOWS: define internal i32 @foo_internal.resolver() { -// LINUX: define{{.*}} i32 @bar2() -// LINUX: call i32 @foo_inline.ifunc() +// ITANIUM: define{{.*}} i32 @bar2() +// ITANIUM: call i32 @foo_inline.ifunc() // WINDOWS: define dso_local i32 @bar2() // WINDOWS: call i32 @foo_inline.resolver() -// LINUX: define weak_odr ptr @foo_inline.resolver() comdat -// LINUX: call void @__cpu_indicator_init() -// LINUX: ret ptr @foo_inline.arch_sandybridge -// LINUX: ret ptr @foo_inline.arch_ivybridge -// LINUX: ret ptr @foo_inline.sse4.2 -// LINUX: ret ptr @foo_inline +// ITANIUM: define weak_odr ptr @foo_inline.resolver() +// LINUX-SAME: comdat +// ITANIUM: call void @__cpu_indicator_init() +// ITANIUM: ret ptr @foo_inline.arch_sandybridge +// ITANIUM: ret ptr @foo_inline.arch_ivybridge +// ITANIUM: ret ptr @foo_inline.sse4.2 +// ITANIUM: ret ptr @foo_inline // WINDOWS: define weak_odr dso_local i32 @foo_inline.resolver() comdat // WINDOWS: call void @__cpu_indicator_init() @@ -297,38 +303,40 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: call i32 @foo_inline.sse4.2 // WINDOWS: call i32 @foo_inline -// LINUX: define{{.*}} void @bar3() -// LINUX: call void @foo_decls.ifunc() +// ITANIUM: define{{.*}} void @bar3() +// ITANIUM: call void @foo_decls.ifunc() // WINDOWS: define dso_local void @bar3() // WINDOWS: call void @foo_decls.resolver() -// LINUX: define weak_odr ptr @foo_decls.resolver() comdat -// LINUX: ret ptr @foo_decls.sse4.2 -// LINUX: ret ptr @foo_decls +// ITANIUM: define weak_odr ptr @foo_decls.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @foo_decls.sse4.2 +// ITANIUM: ret ptr @foo_decls // WINDOWS: define weak_odr dso_local void @foo_decls.resolver() comdat // WINDOWS: call void @foo_decls.sse4.2 // WINDOWS: call void @foo_decls -// LINUX: define{{.*}} void @bar4() -// LINUX: call void @foo_multi.ifunc(i32 noundef 1, double noundef 5.{{[0+e]*}}) +// ITANIUM: define{{.*}} void @bar4() +// ITANIUM: call void @foo_multi.ifunc(i32 noundef 1, double noundef 5.{{[0+e]*}}) // WINDOWS: define dso_local void @bar4() // WINDOWS: call void @foo_multi.resolver(i32 noundef 1, double noundef 5.{{[0+e]*}}) -// LINUX: define weak_odr ptr @foo_multi.resolver() comdat -// LINUX: and i32 %{{.*}}, 4352 -// LINUX: icmp eq i32 %{{.*}}, 4352 -// LINUX: ret ptr @foo_multi.fma4_sse4.2 -// LINUX: icmp eq i32 %{{.*}}, 12 -// LINUX: and i32 %{{.*}}, 4352 -// LINUX: icmp eq i32 %{{.*}}, 4352 -// LINUX: ret ptr @foo_multi.arch_ivybridge_fma4_sse4.2 -// LINUX: and i32 %{{.*}}, 768 -// LINUX: icmp eq i32 %{{.*}}, 768 -// LINUX: ret ptr @foo_multi.avx_sse4.2 -// LINUX: ret ptr @foo_multi +// ITANIUM: define weak_odr ptr @foo_multi.resolver() +// LINUX-SAME: comdat +// ITANIUM: and i32 %{{.*}}, 4352 +// ITANIUM: icmp eq i32 %{{.*}}, 4352 +// ITANIUM: ret ptr @foo_multi.fma4_sse4.2 +// ITANIUM: icmp eq i32 %{{.*}}, 12 +// ITANIUM: and i32 %{{.*}}, 4352 +// ITANIUM: icmp eq i32 %{{.*}}, 4352 +// ITANIUM: ret ptr @foo_multi.arch_ivybridge_fma4_sse4.2 +// ITANIUM: and i32 %{{.*}}, 768 +// ITANIUM: icmp eq i32 %{{.*}}, 768 +// ITANIUM: ret ptr @foo_multi.avx_sse4.2 +// ITANIUM: ret ptr @foo_multi // WINDOWS: define weak_odr dso_local void @foo_multi.resolver(i32 %0, double %1) comdat // WINDOWS: and i32 %{{.*}}, 4352 @@ -347,12 +355,12 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: call void @foo_multi(i32 %0, double %1) // WINDOWS-NEXT: ret void -// LINUX: define{{.*}} i32 @fwd_decl_default() -// LINUX: ret i32 2 -// LINUX: define{{.*}} i32 @fwd_decl_avx.avx() -// LINUX: ret i32 2 -// LINUX: define{{.*}} i32 @fwd_decl_avx() -// LINUX: ret i32 2 +// ITANIUM: define{{.*}} i32 @fwd_decl_default() +// ITANIUM: ret i32 2 +// ITANIUM: define{{.*}} i32 @fwd_decl_avx.avx() +// ITANIUM: ret i32 2 +// ITANIUM: define{{.*}} i32 @fwd_decl_avx() +// ITANIUM: ret i32 2 // WINDOWS: define dso_local i32 @fwd_decl_default() // WINDOWS: ret i32 2 @@ -361,21 +369,23 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: define dso_local i32 @fwd_decl_avx() // WINDOWS: ret i32 2 -// LINUX: define{{.*}} void @bar5() -// LINUX: call i32 @fwd_decl_default.ifunc() -// LINUX: call i32 @fwd_decl_avx.ifunc() +// ITANIUM: define{{.*}} void @bar5() +// ITANIUM: call i32 @fwd_decl_default.ifunc() +// ITANIUM: call i32 @fwd_decl_avx.ifunc() // WINDOWS: define dso_local void @bar5() // WINDOWS: call i32 @fwd_decl_default.resolver() // WINDOWS: call i32 @fwd_decl_avx.resolver() -// LINUX: define weak_odr ptr @fwd_decl_default.resolver() comdat -// LINUX: call void @__cpu_indicator_init() -// LINUX: ret ptr @fwd_decl_default -// LINUX: define weak_odr ptr @fwd_decl_avx.resolver() comdat -// LINUX: call void @__cpu_indicator_init() -// LINUX: ret ptr @fwd_decl_avx.avx -// LINUX: ret ptr @fwd_decl_avx +// ITANIUM: define weak_odr ptr @fwd_decl_default.resolver() +// LINUX-SAME: comdat +// ITANIUM: call void @__cpu_indicator_init() +// ITANIUM: ret ptr @fwd_decl_default +// ITANIUM: define weak_odr ptr @fwd_decl_avx.resolver() +// LINUX-SAME: comdat +// ITANIUM: call void @__cpu_indicator_init() +// ITANIUM: ret ptr @fwd_decl_avx.avx +// ITANIUM: ret ptr @fwd_decl_avx // WINDOWS: define weak_odr dso_local i32 @fwd_decl_default.resolver() comdat // WINDOWS: call void @__cpu_indicator_init() @@ -385,55 +395,55 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: call i32 @fwd_decl_avx.avx // WINDOWS: call i32 @fwd_decl_avx -// LINUX: define{{.*}} i32 @changed_to_mv.avx() -// LINUX: define{{.*}} i32 @changed_to_mv.fma4() +// ITANIUM: define{{.*}} i32 @changed_to_mv.avx() +// ITANIUM: define{{.*}} i32 @changed_to_mv.fma4() // WINDOWS: define dso_local i32 @changed_to_mv.avx() // WINDOWS: define dso_local i32 @changed_to_mv.fma4() -// LINUX: define linkonce void @foo_used(i32 noundef %{{.*}}, double noundef %{{.*}}) -// LINUX-NOT: @foo_used.avx_sse4.2( -// LINUX-NOT: @foo_used2( -// LINUX: define linkonce void @foo_used2.avx_sse4.2(i32 noundef %{{.*}}, double noundef %{{.*}}) +// ITANIUM: define linkonce void @foo_used(i32 noundef %{{.*}}, double noundef %{{.*}}) +// ITANIUM-NOT: @foo_used.avx_sse4.2( +// ITANIUM-NOT: @foo_used2( +// ITANIUM: define linkonce void @foo_used2.avx_sse4.2(i32 noundef %{{.*}}, double noundef %{{.*}}) // WINDOWS: define linkonce_odr dso_local void @foo_used(i32 noundef %{{.*}}, double noundef %{{.*}}) // WINDOWS-NOT: @foo_used.avx_sse4.2( // WINDOWS-NOT: @foo_used2( // WINDOWS: define linkonce_odr dso_local void @foo_used2.avx_sse4.2(i32 noundef %{{.*}}, double noundef %{{.*}}) -// LINUX: declare i32 @foo.arch_sandybridge() +// ITANIUM: declare i32 @foo.arch_sandybridge() // WINDOWS: declare dso_local i32 @foo.arch_sandybridge() -// LINUX: define linkonce i32 @foo_inline.sse4.2() -// LINUX: ret i32 0 +// ITANIUM: define linkonce i32 @foo_inline.sse4.2() +// ITANIUM: ret i32 0 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.sse4.2() // WINDOWS: ret i32 0 -// LINUX: declare i32 @foo_inline.arch_sandybridge() +// ITANIUM: declare i32 @foo_inline.arch_sandybridge() // WINDOWS: declare dso_local i32 @foo_inline.arch_sandybridge() -// LINUX: define linkonce i32 @foo_inline.arch_ivybridge() -// LINUX: ret i32 1 -// LINUX: define linkonce i32 @foo_inline() -// LINUX: ret i32 2 +// ITANIUM: define linkonce i32 @foo_inline.arch_ivybridge() +// ITANIUM: ret i32 1 +// ITANIUM: define linkonce i32 @foo_inline() +// ITANIUM: ret i32 2 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_ivybridge() // WINDOWS: ret i32 1 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline() // WINDOWS: ret i32 2 -// LINUX: define linkonce void @foo_decls() -// LINUX: define linkonce void @foo_decls.sse4.2() +// ITANIUM: define linkonce void @foo_decls() +// ITANIUM: define linkonce void @foo_decls.sse4.2() // WINDOWS: define linkonce_odr dso_local void @foo_decls() // WINDOWS: define linkonce_odr dso_local void @foo_decls.sse4.2() -// LINUX: define linkonce void @foo_multi(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) -// LINUX: define linkonce void @foo_multi.avx_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) -// LINUX: define linkonce void @foo_multi.fma4_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) -// LINUX: define linkonce void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) +// ITANIUM: define linkonce void @foo_multi(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) +// ITANIUM: define linkonce void @foo_multi.avx_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) +// ITANIUM: define linkonce void @foo_multi.fma4_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) +// ITANIUM: define linkonce void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) // WINDOWS: define linkonce_odr dso_local void @foo_multi(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) // WINDOWS: define linkonce_odr dso_local void @foo_multi.avx_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) @@ -441,22 +451,23 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: define linkonce_odr dso_local void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 noundef %{{[^,]+}}, double noundef %{{[^\)]+}}) // Ensure that we emit the 'static' function here. -// LINUX: define linkonce void @pr50025() -// LINUX: call void @must_be_emitted -// LINUX: define internal void @must_be_emitted() +// ITANIUM: define linkonce void @pr50025() +// ITANIUM: call void @must_be_emitted +// ITANIUM: define internal void @must_be_emitted() // WINDOWS: define linkonce_odr dso_local void @pr50025() #{{[0-9]*}} comdat // WINDOWS: call void @must_be_emitted // WINDOWS: define internal void @must_be_emitted() -// LINUX: define linkonce void @pr50025c() -// LINUX: call void @pr50025b.ifunc() +// ITANIUM: define linkonce void @pr50025c() +// ITANIUM: call void @pr50025b.ifunc() // WINDOWS: define linkonce_odr dso_local void @pr50025c() #{{[0-9]*}} comdat // WINDOWS: call void @pr50025b.resolver() -// LINUX: define weak_odr ptr @pr50025b.resolver() comdat -// LINUX: ret ptr @pr50025b -// LINUX: define linkonce void @pr50025b() -// LINUX: call void @must_be_emitted() +// ITANIUM: define weak_odr ptr @pr50025b.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @pr50025b +// ITANIUM: define linkonce void @pr50025b() +// ITANIUM: call void @must_be_emitted() // WINDOWS: define weak_odr dso_local void @pr50025b.resolver() comdat // WINDOWS: musttail call void @pr50025b() // WINDOWS: define linkonce_odr dso_local void @pr50025b() #{{[0-9]*}} comdat diff --git a/clang/test/CodeGen/bounds-checking.c b/clang/test/CodeGen/bounds-checking.c index 8100e30d0650adca140e08d8a262b45a32793128..636d4f289e247863f1f312c57e03792f1d99f616 100644 --- a/clang/test/CodeGen/bounds-checking.c +++ b/clang/test/CodeGen/bounds-checking.c @@ -69,6 +69,7 @@ int f7(union U *u, int i) { return u->c[i]; } + char B[10]; char B2[10]; // CHECK-LABEL: @f8 @@ -81,12 +82,3 @@ void f8(int i, int k) { // NOOPTARRAY: call void @llvm.ubsantrap(i8 4) B2[k] = '\0'; } - -// See commit 9a954c6 that caused a SEGFAULT in this code. -struct S { - __builtin_va_list ap; -} *s; -// CHECK-LABEL: @f9 -struct S *f9(int i) { - return &s[i]; -} diff --git a/clang/test/CodeGen/fat-lto-objects.c b/clang/test/CodeGen/fat-lto-objects.c index 95207e77c244cc943799b3663f80e4a779528f06..5c8ad1fd93c4b3858e7f482cc95346ca6b320d7a 100644 --- a/clang/test/CodeGen/fat-lto-objects.c +++ b/clang/test/CodeGen/fat-lto-objects.c @@ -35,8 +35,7 @@ // SPLIT: ![[#]] = !{i32 1, !"EnableSplitLTOUnit", i32 1} // NOSPLIT: ![[#]] = !{i32 1, !"EnableSplitLTOUnit", i32 0} -/// Check that the ThinLTO metadata is set true for both full and thin LTO, since FatLTO is based on UnifiedLTO. -// FULL: ![[#]] = !{i32 1, !"ThinLTO", i32 1} +// FULL-NOT: ![[#]] = !{i32 1, !"ThinLTO", i32 0} // THIN-NOT: ![[#]] = !{i32 1, !"ThinLTO", i32 0} /// FatLTO always uses UnifiedLTO. It's an error if they aren't set together diff --git a/clang/test/CodeGen/ifunc.c b/clang/test/CodeGen/ifunc.c index 0b0a0549620f8b8679a4bb116919947bc029c21e..3aa29f7dff74dec7cf17458ff96bbc7eaf2985d3 100644 --- a/clang/test/CodeGen/ifunc.c +++ b/clang/test/CodeGen/ifunc.c @@ -3,6 +3,14 @@ // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsanitize=memory -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN +// RUN: %clang_cc1 -triple arm64-apple-macosx -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-macosx -O2 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx -O2 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN +// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN +// RUN: %clang_cc1 -triple arm64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN +// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN int foo(int) __attribute__ ((ifunc("foo_ifunc"))); @@ -43,10 +51,14 @@ void* goo_ifunc(void) { // CHECK: call i32 @foo(i32 // CHECK: call void @goo() -// SAN: define internal nonnull ptr @foo_ifunc() #[[#FOO_IFUNC:]] { +// SAN: define internal nonnull {{(noundef )?}}ptr @foo_ifunc() #[[#FOO_IFUNC:]] { +// MACSAN: define internal nonnull {{(noundef )?}}ptr @foo_ifunc() #[[#FOO_IFUNC:]] { -// SAN: define dso_local noalias ptr @goo_ifunc() #[[#GOO_IFUNC:]] { +// SAN: define dso_local noalias {{(noundef )?}}ptr @goo_ifunc() #[[#GOO_IFUNC:]] { +// MACSAN: define noalias {{(noundef )?}}ptr @goo_ifunc() #[[#GOO_IFUNC:]] { // SAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} +// MACSAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} // SAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} +// MACSAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} diff --git a/clang/test/CodeGen/invalid_global_asm.c b/clang/test/CodeGen/invalid_global_asm.c index 5b7e8b43d752d873ef7f492f4b090dca34a7727b..d5645f7fc92bf442792830986aab093c8d0b17c4 100644 --- a/clang/test/CodeGen/invalid_global_asm.c +++ b/clang/test/CodeGen/invalid_global_asm.c @@ -1,5 +1,10 @@ // REQUIRES: arm-registered-target // RUN: not %clang_cc1 -emit-obj -triple armv6-unknown-unknown -o %t %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -emit-obj -triple armv6-unknown-unknown -flto -o %t %s 2>&1 | FileCheck %s + +/// Test the diagnostic behavior considering the whole system including the driver. +// RUN: not %clang --target=armv6-unknown-unknown -c -flto=thin -o %t %s 2>&1 | FileCheck %s #pragma clang diagnostic ignored "-Wmissing-noreturn" __asm__(".Lfoo: movw r2, #:lower16:.Lbar - .Lfoo"); // CHECK: :1:8: error: instruction requires: armv6t2 +// CHECK-NOT: error: diff --git a/clang/test/CodeGen/isfpclass.c b/clang/test/CodeGen/isfpclass.c index 34873c08e04f87e9a95b624969ef7e78bab8141c..88d7a21b9733d864bdb433a934f3b144fe445d75 100644 --- a/clang/test/CodeGen/isfpclass.c +++ b/clang/test/CodeGen/isfpclass.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // RUN: %clang_cc1 -triple aarch64-linux-gnu -S -O1 -emit-llvm %s -o - | FileCheck %s -// CHECK-LABEL: define dso_local i1 @check_isfpclass_finite +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_finite // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call float @llvm.fabs.f32(float [[X]]) @@ -12,7 +12,7 @@ _Bool check_isfpclass_finite(float x) { return __builtin_isfpclass(x, 504 /*Finite*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_finite_strict +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_finite_strict // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[X]], i32 504) #[[ATTR6:[0-9]+]] @@ -23,7 +23,7 @@ _Bool check_isfpclass_finite_strict(float x) { return __builtin_isfpclass(x, 504 /*Finite*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_nan_f32 +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_nan_f32 // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = fcmp uno float [[X]], 0.000000e+00 @@ -33,7 +33,7 @@ _Bool check_isfpclass_nan_f32(float x) { return __builtin_isfpclass(x, 3 /*NaN*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_nan_f32_strict +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_nan_f32_strict // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[X]], i32 3) #[[ATTR6]] @@ -44,7 +44,7 @@ _Bool check_isfpclass_nan_f32_strict(float x) { return __builtin_isfpclass(x, 3 /*NaN*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_snan_f64 +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_snan_f64 // CHECK-SAME: (double noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f64(double [[X]], i32 1) @@ -54,7 +54,7 @@ _Bool check_isfpclass_snan_f64(double x) { return __builtin_isfpclass(x, 1 /*SNaN*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_snan_f64_strict +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_snan_f64_strict // CHECK-SAME: (double noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f64(double [[X]], i32 1) #[[ATTR6]] @@ -65,7 +65,7 @@ _Bool check_isfpclass_snan_f64_strict(double x) { return __builtin_isfpclass(x, 1 /*NaN*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_zero_f16 +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_zero_f16 // CHECK-SAME: (half noundef [[X:%.*]]) local_unnamed_addr #[[ATTR3]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = fcmp oeq half [[X]], 0xH0000 @@ -75,7 +75,7 @@ _Bool check_isfpclass_zero_f16(_Float16 x) { return __builtin_isfpclass(x, 96 /*Zero*/); } -// CHECK-LABEL: define dso_local i1 @check_isfpclass_zero_f16_strict +// CHECK-LABEL: define dso_local noundef i1 @check_isfpclass_zero_f16_strict // CHECK-SAME: (half noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f16(half [[X]], i32 96) #[[ATTR6]] @@ -86,7 +86,7 @@ _Bool check_isfpclass_zero_f16_strict(_Float16 x) { return __builtin_isfpclass(x, 96 /*Zero*/); } -// CHECK-LABEL: define dso_local i1 @check_isnan +// CHECK-LABEL: define dso_local noundef i1 @check_isnan // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[X]], i32 3) #[[ATTR6]] @@ -97,7 +97,7 @@ _Bool check_isnan(float x) { return __builtin_isnan(x); } -// CHECK-LABEL: define dso_local i1 @check_isinf +// CHECK-LABEL: define dso_local noundef i1 @check_isinf // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[X]], i32 516) #[[ATTR6]] @@ -108,7 +108,7 @@ _Bool check_isinf(float x) { return __builtin_isinf(x); } -// CHECK-LABEL: define dso_local i1 @check_isfinite +// CHECK-LABEL: define dso_local noundef i1 @check_isfinite // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[X]], i32 504) #[[ATTR6]] @@ -119,7 +119,7 @@ _Bool check_isfinite(float x) { return __builtin_isfinite(x); } -// CHECK-LABEL: define dso_local i1 @check_isnormal +// CHECK-LABEL: define dso_local noundef i1 @check_isnormal // CHECK-SAME: (float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[X]], i32 264) #[[ATTR6]] @@ -136,7 +136,7 @@ typedef double __attribute__((ext_vector_type(4))) double4; typedef int __attribute__((ext_vector_type(4))) int4; typedef long __attribute__((ext_vector_type(4))) long4; -// CHECK-LABEL: define dso_local <4 x i32> @check_isfpclass_nan_v4f32 +// CHECK-LABEL: define dso_local noundef <4 x i32> @check_isfpclass_nan_v4f32 // CHECK-SAME: (<4 x float> noundef [[X:%.*]]) local_unnamed_addr #[[ATTR3]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = fcmp uno <4 x float> [[X]], zeroinitializer @@ -147,7 +147,7 @@ int4 check_isfpclass_nan_v4f32(float4 x) { return __builtin_isfpclass(x, 3 /*NaN*/); } -// CHECK-LABEL: define dso_local <4 x i32> @check_isfpclass_nan_strict_v4f32 +// CHECK-LABEL: define dso_local noundef <4 x i32> @check_isfpclass_nan_strict_v4f32 // CHECK-SAME: (<4 x float> noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> [[X]], i32 3) #[[ATTR6]] diff --git a/clang/test/CodeGen/math-builtins-long.c b/clang/test/CodeGen/math-builtins-long.c index f3c328dcbfcd7c8e8e604d7a5246356696d0e1cf..ad0d2122b597fab16352d062310c052a6f28fb64 100644 --- a/clang/test/CodeGen/math-builtins-long.c +++ b/clang/test/CodeGen/math-builtins-long.c @@ -35,7 +35,7 @@ void foo(long double f, long double *l, int *i, const char *c) { __builtin_fabsl(f); // F80: call { x86_fp80, i32 } @llvm.frexp.f80.i32(x86_fp80 %{{.+}}) - // PPC: call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 %{{.+}}) + // PPC: call ppc_fp128 @frexpl(ppc_fp128 noundef %{{.+}}, ptr noundef %{{.+}}) // X86F128: call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %{{.+}}) // PPCF128: call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %{{.+}}) __builtin_frexpl(f,i); diff --git a/clang/test/CodeGen/ms-mixed-ptr-sizes.c b/clang/test/CodeGen/ms-mixed-ptr-sizes.c index a853c6083cb8baea1d016ebe58c6bb3f5d430fe2..89d05fd30b72c2bfb1ecbb3973deb17551d67bf2 100644 --- a/clang/test/CodeGen/ms-mixed-ptr-sizes.c +++ b/clang/test/CodeGen/ms-mixed-ptr-sizes.c @@ -49,7 +49,7 @@ void test_other(struct Foo *f, __attribute__((address_space(10))) int *i) { } int test_compare1(int *__ptr32 __uptr i, int *__ptr64 j) { - // ALL-LABEL: define dso_local i32 @test_compare1 + // ALL-LABEL: define dso_local noundef i32 @test_compare1 // X64: %{{.+}} = addrspacecast ptr %j to ptr addrspace(271) // X64: %cmp = icmp eq ptr addrspace(271) %{{.+}}, %i // X86: %{{.+}} = addrspacecast ptr addrspace(272) %j to ptr addrspace(271) @@ -58,7 +58,7 @@ int test_compare1(int *__ptr32 __uptr i, int *__ptr64 j) { } int test_compare2(int *__ptr32 __sptr i, int *__ptr64 j) { - // ALL-LABEL: define dso_local i32 @test_compare2 + // ALL-LABEL: define dso_local noundef i32 @test_compare2 // X64: %{{.+}} = addrspacecast ptr %j to ptr addrspace(270) // X64: %cmp = icmp eq ptr addrspace(270) %{{.+}}, %i // X86: %{{.+}} = addrspacecast ptr addrspace(272) %j to ptr @@ -67,7 +67,7 @@ int test_compare2(int *__ptr32 __sptr i, int *__ptr64 j) { } int test_compare3(int *__ptr32 __uptr i, int *__ptr64 j) { - // ALL-LABEL: define dso_local i32 @test_compare3 + // ALL-LABEL: define dso_local noundef i32 @test_compare3 // X64: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr // X64: %cmp = icmp eq ptr %{{.+}}, %j // X86: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr addrspace(272) @@ -76,7 +76,7 @@ int test_compare3(int *__ptr32 __uptr i, int *__ptr64 j) { } int test_compare4(int *__ptr32 __sptr i, int *__ptr64 j) { - // ALL-LABEL: define dso_local i32 @test_compare4 + // ALL-LABEL: define dso_local noundef i32 @test_compare4 // X64: %{{.+}} = addrspacecast ptr addrspace(270) %i to ptr // X64: %cmp = icmp eq ptr %{{.+}}, %j // X86: %{{.+}} = addrspacecast ptr %i to ptr addrspace(272) diff --git a/clang/test/CodeGen/nofpclass.c b/clang/test/CodeGen/nofpclass.c index 7fea8192cda7512406775f508bf0b748b458f08c..daaf24e77b09d7a262701731a27ec0c7ed359866 100644 --- a/clang/test/CodeGen/nofpclass.c +++ b/clang/test/CodeGen/nofpclass.c @@ -1,4 +1,4 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --version 2 +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 2 // REQUIRES: x86-registered-target // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -ffinite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CFINITEONLY %s // RUN: %clang_cc1 -x cl -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -cl-finite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CLFINITEONLY %s @@ -733,7 +733,7 @@ _Complex double defined_complex_func_f64_ret(_Complex double c) { // CLFINITEONLY-NEXT: [[MUL_R:%.*]] = fsub nnan ninf float [[MUL_AC]], [[MUL_BD]] // CLFINITEONLY-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half // CLFINITEONLY-NEXT: [[UNPROMOTION9:%.*]] = fptrunc float [[MUL_I]] to half -// CLFINITEONLY-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> undef, half [[UNPROMOTION]], i64 0 +// CLFINITEONLY-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[UNPROMOTION]], i64 0 // CLFINITEONLY-NEXT: [[RETVAL_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[RETVAL_SROA_0_0_VEC_INSERT]], half [[UNPROMOTION9]], i64 1 // CLFINITEONLY-NEXT: ret <2 x half> [[RETVAL_SROA_0_2_VEC_INSERT]] // @@ -930,7 +930,7 @@ _Complex _Float16 defined_complex_func_f16_ret(_Complex _Float16 c) { // CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i64 0, i32 1 // CLFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[INDIRECT_ARG_TEMP]], align 8 // CLFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8 -// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> undef, half [[CF16_REAL]], i64 0 +// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[CF16_REAL]], i64 0 // CLFINITEONLY-NEXT: [[COERCE5_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[COERCE5_SROA_0_0_VEC_INSERT]], half [[CF16_IMAG]], i64 1 // CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) @variadic(float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR10]] // CLFINITEONLY-NEXT: ret float [[CALL]] @@ -1181,7 +1181,7 @@ float call_variadic(float f32, double f64, _Float16 f16, // CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i64 0, i32 1 // CLFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[INDIRECT_ARG_TEMP]], align 8 // CLFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8 -// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> undef, half [[CF16_REAL]], i64 0 +// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[CF16_REAL]], i64 0 // CLFINITEONLY-NEXT: [[COERCE5_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[COERCE5_SROA_0_0_VEC_INSERT]], half [[CF16_IMAG]], i64 1 // CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) [[FPTR]](float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR10]] // CLFINITEONLY-NEXT: ret float [[CALL]] diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index c5cb922576dd461599a64244b41505f937d6daa7..acff367d50eb91ef6f74ea9d25105d2778549fa3 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -176,12 +176,12 @@ // RUN: %clang_cc1 -triple amdgcn-unknown -target-cpu hawaii -o - -emit-llvm %s \ // RUN: | FileCheck %s -check-prefix=R600SI -// R600SI: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8" +// R600SI: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" // Test default -target-cpu // RUN: %clang_cc1 -triple amdgcn-unknown -o - -emit-llvm %s \ // RUN: | FileCheck %s -check-prefix=R600SIDefault -// R600SIDefault: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8" +// R600SIDefault: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" // RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=AARCH64 diff --git a/clang/test/CodeGenCUDA/link-builtin-bitcode-denormal-fp-mode.cu b/clang/test/CodeGenCUDA/link-builtin-bitcode-denormal-fp-mode.cu index f12eacfb53fab37db313476a2acf62e09037a212..ef02668c3697bfcf142e5d605a1424dcc09cb1ee 100644 --- a/clang/test/CodeGenCUDA/link-builtin-bitcode-denormal-fp-mode.cu +++ b/clang/test/CodeGenCUDA/link-builtin-bitcode-denormal-fp-mode.cu @@ -111,16 +111,16 @@ __global__ void kernel_f64(double* out, double* a, double* b, double* c) { } } -// INTERNALIZE: define internal half @do_f16_stuff({{.*}}) #[[$FUNCATTR:[0-9]+]] -// INTERNALIZE: define internal float @do_f32_stuff({{.*}}) #[[$FUNCATTR]] -// INTERNALIZE: define internal double @do_f64_stuff({{.*}}) #[[$FUNCATTR]] -// INTERNALIZE: define internal float @weak_do_f32_stuff({{.*}}) #[[$WEAK_FUNCATTR:[0-9]+]] +// INTERNALIZE: define internal {{(noundef )?}}half @do_f16_stuff({{.*}}) #[[$FUNCATTR:[0-9]+]] +// INTERNALIZE: define internal {{(noundef )?}}float @do_f32_stuff({{.*}}) #[[$FUNCATTR]] +// INTERNALIZE: define internal {{(noundef )?}}double @do_f64_stuff({{.*}}) #[[$FUNCATTR]] +// INTERNALIZE: define internal {{(noundef )?}}float @weak_do_f32_stuff({{.*}}) #[[$WEAK_FUNCATTR:[0-9]+]] -// NOINTERNALIZE: define dso_local half @do_f16_stuff({{.*}}) #[[$FUNCATTR:[0-9]+]] -// NOINTERNALIZE: define dso_local float @do_f32_stuff({{.*}}) #[[$FUNCATTR]] -// NOINTERNALIZE: define dso_local double @do_f64_stuff({{.*}}) #[[$FUNCATTR]] -// NOINTERNALIZE: define weak float @weak_do_f32_stuff({{.*}}) #[[$WEAK_FUNCATTR:[0-9]+]] +// NOINTERNALIZE: define dso_local {{(noundef )?}}half @do_f16_stuff({{.*}}) #[[$FUNCATTR:[0-9]+]] +// NOINTERNALIZE: define dso_local {{(noundef )?}}float @do_f32_stuff({{.*}}) #[[$FUNCATTR]] +// NOINTERNALIZE: define dso_local {{(noundef )?}}double @do_f64_stuff({{.*}}) #[[$FUNCATTR]] +// NOINTERNALIZE: define weak {{(noundef )?}}float @weak_do_f32_stuff({{.*}}) #[[$WEAK_FUNCATTR:[0-9]+]] diff --git a/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/clang/test/CodeGenCXX/attr-cpuspecific.cpp index 60cba6da01754dc6b3153868c200e6e8164915e2..225c6a5c742a5f4df3df346603b8545243a3ecc6 100644 --- a/clang/test/CodeGenCXX/attr-cpuspecific.cpp +++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX // RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefix=WINDOWS struct S { diff --git a/clang/test/CodeGenCXX/attr-target-clones.cpp b/clang/test/CodeGenCXX/attr-target-clones.cpp index fd2d38062a71e511b19ec6a46fe92673ea78ff6d..0814df312f4d8d2089ef61473ebd605316946c7c 100644 --- a/clang/test/CodeGenCXX/attr-target-clones.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones.cpp @@ -1,27 +1,31 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS +// DARWIN-NOT: comdat + // Aliases for ifuncs -// LINUX: @_Z10overloadedi.ifunc = weak_odr alias i32 (i32), ptr @_Z10overloadedi -// LINUX: @_Z10overloadedPKc.ifunc = weak_odr alias i32 (ptr), ptr @_Z10overloadedPKc -// LINUX: @_ZN1CIssE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIssE3fooEv -// LINUX: @_ZN1CIisE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIisE3fooEv -// LINUX: @_ZN1CIdfE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIdfE3fooEv +// ITANIUM: @_Z10overloadedi.ifunc = weak_odr alias i32 (i32), ptr @_Z10overloadedi +// ITANIUM: @_Z10overloadedPKc.ifunc = weak_odr alias i32 (ptr), ptr @_Z10overloadedPKc +// ITANIUM: @_ZN1CIssE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIssE3fooEv +// ITANIUM: @_ZN1CIisE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIisE3fooEv +// ITANIUM: @_ZN1CIdfE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIdfE3fooEv // Overloaded ifuncs -// LINUX: @_Z10overloadedi = weak_odr ifunc i32 (i32), ptr @_Z10overloadedi.resolver -// LINUX: @_Z10overloadedPKc = weak_odr ifunc i32 (ptr), ptr @_Z10overloadedPKc.resolver +// ITANIUM: @_Z10overloadedi = weak_odr ifunc i32 (i32), ptr @_Z10overloadedi.resolver +// ITANIUM: @_Z10overloadedPKc = weak_odr ifunc i32 (ptr), ptr @_Z10overloadedPKc.resolver // struct 'C' ifuncs, note the 'float, U' one doesn't get one. -// LINUX: @_ZN1CIssE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIssE3fooEv.resolver -// LINUX: @_ZN1CIisE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIisE3fooEv.resolver -// LINUX: @_ZN1CIdfE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIdfE3fooEv.resolver +// ITANIUM: @_ZN1CIssE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIssE3fooEv.resolver +// ITANIUM: @_ZN1CIisE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIisE3fooEv.resolver +// ITANIUM: @_ZN1CIdfE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIdfE3fooEv.resolver int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return 1; } -// LINUX: define {{.*}}i32 @_Z10overloadedi.sse4.2.0(i32{{.+}}) -// LINUX: define {{.*}}i32 @_Z10overloadedi.default.1(i32{{.+}}) -// LINUX: define weak_odr ptr @_Z10overloadedi.resolver() comdat -// LINUX: ret ptr @_Z10overloadedi.sse4.2.0 -// LINUX: ret ptr @_Z10overloadedi.default.1 +// ITANIUM: define {{.*}}i32 @_Z10overloadedi.sse4.2.0(i32{{.+}}) +// ITANIUM: define {{.*}}i32 @_Z10overloadedi.default.1(i32{{.+}}) +// ITANIUM: define weak_odr ptr @_Z10overloadedi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_Z10overloadedi.sse4.2.0 +// ITANIUM: ret ptr @_Z10overloadedi.default.1 // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.sse4.2.0"(i32{{.+}}) // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.default.1"(i32{{.+}}) @@ -30,11 +34,12 @@ int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return // WINDOWS: call i32 @"?overloaded@@YAHH@Z.default.1" int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const char *) { return 2; } -// LINUX: define {{.*}}i32 @_Z10overloadedPKc.arch_ivybridge.0(ptr{{.+}}) -// LINUX: define {{.*}}i32 @_Z10overloadedPKc.default.1(ptr{{.+}}) -// LINUX: define weak_odr ptr @_Z10overloadedPKc.resolver() comdat -// LINUX: ret ptr @_Z10overloadedPKc.arch_ivybridge.0 -// LINUX: ret ptr @_Z10overloadedPKc.default.1 +// ITANIUM: define {{.*}}i32 @_Z10overloadedPKc.arch_ivybridge.0(ptr{{.+}}) +// ITANIUM: define {{.*}}i32 @_Z10overloadedPKc.default.1(ptr{{.+}}) +// ITANIUM: define weak_odr ptr @_Z10overloadedPKc.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_Z10overloadedPKc.arch_ivybridge.0 +// ITANIUM: ret ptr @_Z10overloadedPKc.default.1 // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0"(ptr{{.+}}) // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.default.1"(ptr{{.+}}) @@ -44,10 +49,10 @@ int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const void use_overloaded() { overloaded(1); - // LINUX: call noundef i32 @_Z10overloadedi + // ITANIUM: call noundef i32 @_Z10overloadedi // WINDOWS: call noundef i32 @"?overloaded@@YAHH@Z" overloaded(nullptr); - // LINUX: call noundef i32 @_Z10overloadedPKc + // ITANIUM: call noundef i32 @_Z10overloadedPKc // WINDOWS: call noundef i32 @"?overloaded@@YAHPEBD@Z" } @@ -71,53 +76,56 @@ int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 3;} void uses_specialized() { C c; c.foo(); - // LINUX: call noundef i32 @_ZN1CIssE3fooEv(ptr + // ITANIUM: call noundef i32 @_ZN1CIssE3fooEv(ptr // WINDOWS: call noundef i32 @"?foo@?$C@FF@@QEAAHXZ"(ptr C c2; c2.foo(); - // LINUX: call noundef i32 @_ZN1CIisE3fooEv(ptr + // ITANIUM: call noundef i32 @_ZN1CIisE3fooEv(ptr // WINDOWS: call noundef i32 @"?foo@?$C@HF@@QEAAHXZ"(ptr C c3; c3.foo(); // Note this is not an ifunc/mv - // LINUX: call noundef i32 @_ZN1CIfsE3fooEv(ptr + // ITANIUM: call noundef i32 @_ZN1CIfsE3fooEv(ptr // WINDOWS: call noundef i32 @"?foo@?$C@MF@@QEAAHXZ"(ptr C c4; c4.foo(); - // LINUX: call noundef i32 @_ZN1CIdfE3fooEv(ptr + // ITANIUM: call noundef i32 @_ZN1CIdfE3fooEv(ptr // WINDOWS: call noundef i32 @"?foo@?$C@NM@@QEAAHXZ"(ptr } -// LINUX: define weak_odr ptr @_ZN1CIssE3fooEv.resolver() comdat -// LINUX: ret ptr @_ZN1CIssE3fooEv.sse4.2.0 -// LINUX: ret ptr @_ZN1CIssE3fooEv.default.1 +// ITANIUM: define weak_odr ptr @_ZN1CIssE3fooEv.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN1CIssE3fooEv.sse4.2.0 +// ITANIUM: ret ptr @_ZN1CIssE3fooEv.default.1 // WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ"(ptr // WINDOWS: call i32 @"?foo@?$C@FF@@QEAAHXZ.sse4.2.0" // WINDOWS: call i32 @"?foo@?$C@FF@@QEAAHXZ.default.1" -// LINUX: define weak_odr ptr @_ZN1CIisE3fooEv.resolver() comdat -// LINUX: ret ptr @_ZN1CIisE3fooEv.sse4.2.0 -// LINUX: ret ptr @_ZN1CIisE3fooEv.default.1 +// ITANIUM: define weak_odr ptr @_ZN1CIisE3fooEv.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN1CIisE3fooEv.sse4.2.0 +// ITANIUM: ret ptr @_ZN1CIisE3fooEv.default.1 // WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ"(ptr // WINDOWS: call i32 @"?foo@?$C@HF@@QEAAHXZ.sse4.2.0" // WINDOWS: call i32 @"?foo@?$C@HF@@QEAAHXZ.default.1" -// LINUX: define weak_odr ptr @_ZN1CIdfE3fooEv.resolver() comdat -// LINUX: ret ptr @_ZN1CIdfE3fooEv.sse4.2.0 -// LINUX: ret ptr @_ZN1CIdfE3fooEv.default.1 +// ITANIUM: define weak_odr ptr @_ZN1CIdfE3fooEv.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN1CIdfE3fooEv.sse4.2.0 +// ITANIUM: ret ptr @_ZN1CIdfE3fooEv.default.1 // WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ"(ptr // WINDOWS: call i32 @"?foo@?$C@NM@@QEAAHXZ.sse4.2.0" // WINDOWS: call i32 @"?foo@?$C@NM@@QEAAHXZ.default.1" -// LINUX: define {{.*}}i32 @_ZN1CIssE3fooEv.sse4.2.0(ptr -// LINUX: define {{.*}}i32 @_ZN1CIssE3fooEv.default.1(ptr -// LINUX: define {{.*}}i32 @_ZN1CIisE3fooEv.sse4.2.0(ptr -// LINUX: define {{.*}}i32 @_ZN1CIisE3fooEv.default.1(ptr -// LINUX: define {{.*}}i32 @_ZN1CIdfE3fooEv.sse4.2.0(ptr -// LINUX: define {{.*}}i32 @_ZN1CIdfE3fooEv.default.1(ptr +// ITANIUM: define {{.*}}i32 @_ZN1CIssE3fooEv.sse4.2.0(ptr +// ITANIUM: define {{.*}}i32 @_ZN1CIssE3fooEv.default.1(ptr +// ITANIUM: define {{.*}}i32 @_ZN1CIisE3fooEv.sse4.2.0(ptr +// ITANIUM: define {{.*}}i32 @_ZN1CIisE3fooEv.default.1(ptr +// ITANIUM: define {{.*}}i32 @_ZN1CIdfE3fooEv.sse4.2.0(ptr +// ITANIUM: define {{.*}}i32 @_ZN1CIdfE3fooEv.default.1(ptr // WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ.sse4.2.0"(ptr // WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ.default.1"(ptr diff --git a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp index 1157450835bda97d546a4667d15575366f6b69b5..8f2fb5ef0df7e057c1d74258abec999ee67fce75 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS // Test ensures that this properly differentiates between types in different // namespaces. @@ -18,15 +19,17 @@ int bar() { return foo(1) + ns::foo(2); } -// LINUX: @_Z3fooi.ifunc = weak_odr ifunc i32 (i32), ptr @_Z3fooi.resolver -// LINUX: @_ZN2ns3fooEi.ifunc = weak_odr ifunc i32 (i32), ptr @_ZN2ns3fooEi.resolver +// DARWIN-NOT: comdat -// LINUX: define{{.*}} i32 @_Z3fooi.sse4.2(i32 noundef %0) -// LINUX: ret i32 0 -// LINUX: define{{.*}} i32 @_Z3fooi.arch_ivybridge(i32 noundef %0) -// LINUX: ret i32 1 -// LINUX: define{{.*}} i32 @_Z3fooi(i32 noundef %0) -// LINUX: ret i32 2 +// ITANIUM: @_Z3fooi.ifunc = weak_odr ifunc i32 (i32), ptr @_Z3fooi.resolver +// ITANIUM: @_ZN2ns3fooEi.ifunc = weak_odr ifunc i32 (i32), ptr @_ZN2ns3fooEi.resolver + +// ITANIUM: define{{.*}} i32 @_Z3fooi.sse4.2(i32 noundef %0) +// ITANIUM: ret i32 0 +// ITANIUM: define{{.*}} i32 @_Z3fooi.arch_ivybridge(i32 noundef %0) +// ITANIUM: ret i32 1 +// ITANIUM: define{{.*}} i32 @_Z3fooi(i32 noundef %0) +// ITANIUM: ret i32 2 // WINDOWS: define dso_local noundef i32 @"?foo@@YAHH@Z.sse4.2"(i32 noundef %0) // WINDOWS: ret i32 0 @@ -35,12 +38,12 @@ int bar() { // WINDOWS: define dso_local noundef i32 @"?foo@@YAHH@Z"(i32 noundef %0) // WINDOWS: ret i32 2 -// LINUX: define{{.*}} i32 @_ZN2ns3fooEi.sse4.2(i32 noundef %0) -// LINUX: ret i32 0 -// LINUX: define{{.*}} i32 @_ZN2ns3fooEi.arch_ivybridge(i32 noundef %0) -// LINUX: ret i32 1 -// LINUX: define{{.*}} i32 @_ZN2ns3fooEi(i32 noundef %0) -// LINUX: ret i32 2 +// ITANIUM: define{{.*}} i32 @_ZN2ns3fooEi.sse4.2(i32 noundef %0) +// ITANIUM: ret i32 0 +// ITANIUM: define{{.*}} i32 @_ZN2ns3fooEi.arch_ivybridge(i32 noundef %0) +// ITANIUM: ret i32 1 +// ITANIUM: define{{.*}} i32 @_ZN2ns3fooEi(i32 noundef %0) +// ITANIUM: ret i32 2 // WINDOWS: define dso_local noundef i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 noundef %0) // WINDOWS: ret i32 0 @@ -49,19 +52,20 @@ int bar() { // WINDOWS: define dso_local noundef i32 @"?foo@ns@@YAHH@Z"(i32 noundef %0) // WINDOWS: ret i32 2 -// LINUX: define{{.*}} i32 @_Z3barv() -// LINUX: call noundef i32 @_Z3fooi.ifunc(i32 noundef 1) -// LINUX: call noundef i32 @_ZN2ns3fooEi.ifunc(i32 noundef 2) +// ITANIUM: define{{.*}} i32 @_Z3barv() +// ITANIUM: call noundef i32 @_Z3fooi.ifunc(i32 noundef 1) +// ITANIUM: call noundef i32 @_ZN2ns3fooEi.ifunc(i32 noundef 2) // WINDOWS: define dso_local noundef i32 @"?bar@@YAHXZ"() // WINDOWS: call noundef i32 @"?foo@@YAHH@Z.resolver"(i32 noundef 1) // WINDOWS: call noundef i32 @"?foo@ns@@YAHH@Z.resolver"(i32 noundef 2) -// LINUX: define weak_odr ptr @_Z3fooi.resolver() comdat -// LINUX: ret ptr @_Z3fooi.arch_sandybridge -// LINUX: ret ptr @_Z3fooi.arch_ivybridge -// LINUX: ret ptr @_Z3fooi.sse4.2 -// LINUX: ret ptr @_Z3fooi +// ITANIUM: define weak_odr ptr @_Z3fooi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_Z3fooi.arch_sandybridge +// ITANIUM: ret ptr @_Z3fooi.arch_ivybridge +// ITANIUM: ret ptr @_Z3fooi.sse4.2 +// ITANIUM: ret ptr @_Z3fooi // WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) comdat // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 %0) @@ -69,11 +73,12 @@ int bar() { // WINDOWS: call i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z"(i32 %0) -// LINUX: define weak_odr ptr @_ZN2ns3fooEi.resolver() comdat -// LINUX: ret ptr @_ZN2ns3fooEi.arch_sandybridge -// LINUX: ret ptr @_ZN2ns3fooEi.arch_ivybridge -// LINUX: ret ptr @_ZN2ns3fooEi.sse4.2 -// LINUX: ret ptr @_ZN2ns3fooEi +// ITANIUM: define weak_odr ptr @_ZN2ns3fooEi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN2ns3fooEi.arch_sandybridge +// ITANIUM: ret ptr @_ZN2ns3fooEi.arch_ivybridge +// ITANIUM: ret ptr @_ZN2ns3fooEi.sse4.2 +// ITANIUM: ret ptr @_ZN2ns3fooEi // WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) comdat // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 %0) @@ -81,8 +86,8 @@ int bar() { // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z"(i32 %0) -// LINUX: declare noundef i32 @_Z3fooi.arch_sandybridge(i32 noundef) -// LINUX: declare noundef i32 @_ZN2ns3fooEi.arch_sandybridge(i32 noundef) +// ITANIUM: declare noundef i32 @_Z3fooi.arch_sandybridge(i32 noundef) +// ITANIUM: declare noundef i32 @_ZN2ns3fooEi.arch_sandybridge(i32 noundef) // WINDOWS: declare dso_local noundef i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 noundef) // WINDOWS: declare dso_local noundef i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 noundef) diff --git a/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp b/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp index 690f44ceb58be84e26d5f4ec62d6fd61156b6e35..f03d5f4914be5343e4a46664b45ec2c2840ea393 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS void temp(); void temp(int); diff --git a/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp b/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp index 614e44ee6df57c1a91dde1d98aac971e5c7526b9..70c8671c73c93048516dc989dec9e0c20ca80751 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS64 +// RUN: %clang_cc1 -std=c++11 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefix=DARWIN struct Foo { Foo(); @@ -16,6 +18,9 @@ void usage() { bar(f); } +// DARWIN-NOT: inalloca( +// LINUX-NOT: inalloca( + // WINDOWS: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z"(ptr inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, ptr %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, ptr %[[O]], i32 0, i32 0 diff --git a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp index cf3ba290714e0bd0d84cec41500c27801561be0a..f956890cf706e321662de83a5f801de3097de786 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS struct S { @@ -65,22 +66,24 @@ int templ_use() { return a.foo(1) + b.foo(2); } -// LINUX: @_ZN1SaSERKS_.ifunc = weak_odr ifunc ptr (ptr, ptr), ptr @_ZN1SaSERKS_.resolver -// LINUX: @_ZNK9ConvertTocv1SEv.ifunc = weak_odr ifunc void (ptr), ptr @_ZNK9ConvertTocv1SEv.resolver -// LINUX: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN1S3fooEi.resolver -// LINUX: @_ZN2S23fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN2S23fooEi.resolver +// DARWIN-NOT: comdat + +// ITANIUM: @_ZN1SaSERKS_.ifunc = weak_odr ifunc ptr (ptr, ptr), ptr @_ZN1SaSERKS_.resolver +// ITANIUM: @_ZNK9ConvertTocv1SEv.ifunc = weak_odr ifunc void (ptr), ptr @_ZNK9ConvertTocv1SEv.resolver +// ITANIUM: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN1S3fooEi.resolver +// ITANIUM: @_ZN2S23fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN2S23fooEi.resolver // Templates: -// LINUX: @_ZN5templIiE3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN5templIiE3fooEi.resolver -// LINUX: @_ZN5templIdE3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN5templIdE3fooEi.resolver - -// LINUX: define{{.*}} i32 @_Z3barv() -// LINUX: %s = alloca %struct.S, align 1 -// LINUX: %s2 = alloca %struct.S, align 1 -// LINUX: %C = alloca %struct.ConvertTo, align 1 -// LINUX: call noundef nonnull align 1 dereferenceable(1) ptr @_ZN1SaSERKS_.ifunc(ptr {{[^,]*}} %s2 -// LINUX: call void @_ZNK9ConvertTocv1SEv.ifunc(ptr {{[^,]*}} %C) -// LINUX: call noundef nonnull align 1 dereferenceable(1) ptr @_ZN1SaSERKS_.ifunc(ptr {{[^,]*}} %s2 -// LINUX: call noundef i32 @_ZN1S3fooEi.ifunc(ptr {{[^,]*}} %s, i32 noundef 0) +// ITANIUM: @_ZN5templIiE3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN5templIiE3fooEi.resolver +// ITANIUM: @_ZN5templIdE3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN5templIdE3fooEi.resolver + +// ITANIUM: define{{.*}} i32 @_Z3barv() +// ITANIUM: %s = alloca %struct.S, align 1 +// ITANIUM: %s2 = alloca %struct.S, align 1 +// ITANIUM: %C = alloca %struct.ConvertTo, align 1 +// ITANIUM: call noundef nonnull align 1 dereferenceable(1) ptr @_ZN1SaSERKS_.ifunc(ptr {{[^,]*}} %s2 +// ITANIUM: call void @_ZNK9ConvertTocv1SEv.ifunc(ptr {{[^,]*}} %C) +// ITANIUM: call noundef nonnull align 1 dereferenceable(1) ptr @_ZN1SaSERKS_.ifunc(ptr {{[^,]*}} %s2 +// ITANIUM: call noundef i32 @_ZN1S3fooEi.ifunc(ptr {{[^,]*}} %s, i32 noundef 0) // WINDOWS: define dso_local noundef i32 @"?bar@@YAHXZ"() // WINDOWS: %s = alloca %struct.S, align 1 @@ -91,27 +94,30 @@ int templ_use() { // WINDOWS: call noundef nonnull align 1 dereferenceable(1) ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(ptr {{[^,]*}} %s2 // WINDOWS: call noundef i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr {{[^,]*}} %s, i32 noundef 0) -// LINUX: define weak_odr ptr @_ZN1SaSERKS_.resolver() comdat -// LINUX: ret ptr @_ZN1SaSERKS_.arch_ivybridge -// LINUX: ret ptr @_ZN1SaSERKS_ +// ITANIUM: define weak_odr ptr @_ZN1SaSERKS_.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN1SaSERKS_.arch_ivybridge +// ITANIUM: ret ptr @_ZN1SaSERKS_ // WINDOWS: define weak_odr dso_local ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(ptr %0, ptr %1) // WINDOWS: call ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.arch_ivybridge" // WINDOWS: call ptr @"??4S@@QEAAAEAU0@AEBU0@@Z" -// LINUX: define weak_odr ptr @_ZNK9ConvertTocv1SEv.resolver() comdat -// LINUX: ret ptr @_ZNK9ConvertTocv1SEv.arch_ivybridge -// LINUX: ret ptr @_ZNK9ConvertTocv1SEv +// ITANIUM: define weak_odr ptr @_ZNK9ConvertTocv1SEv.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZNK9ConvertTocv1SEv.arch_ivybridge +// ITANIUM: ret ptr @_ZNK9ConvertTocv1SEv // WINDOWS: define weak_odr dso_local void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(ptr %0, ptr %1) // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.arch_ivybridge" // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ" -// LINUX: define weak_odr ptr @_ZN1S3fooEi.resolver() comdat -// LINUX: ret ptr @_ZN1S3fooEi.arch_sandybridge -// LINUX: ret ptr @_ZN1S3fooEi.arch_ivybridge -// LINUX: ret ptr @_ZN1S3fooEi.sse4.2 -// LINUX: ret ptr @_ZN1S3fooEi +// ITANIUM: define weak_odr ptr @_ZN1S3fooEi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN1S3fooEi.arch_sandybridge +// ITANIUM: ret ptr @_ZN1S3fooEi.arch_ivybridge +// ITANIUM: ret ptr @_ZN1S3fooEi.sse4.2 +// ITANIUM: ret ptr @_ZN1S3fooEi // WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge" @@ -119,17 +125,18 @@ int templ_use() { // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2" // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z" -// LINUX: define{{.*}} i32 @_Z4bar2v() -// LINUX: call noundef i32 @_ZN2S23fooEi.ifunc +// ITANIUM: define{{.*}} i32 @_Z4bar2v() +// ITANIUM: call noundef i32 @_ZN2S23fooEi.ifunc // WINDOWS: define dso_local noundef i32 @"?bar2@@YAHXZ"() // WINDOWS: call noundef i32 @"?foo@S2@@QEAAHH@Z.resolver" -// LINUX: define weak_odr ptr @_ZN2S23fooEi.resolver() comdat -// LINUX: ret ptr @_ZN2S23fooEi.arch_sandybridge -// LINUX: ret ptr @_ZN2S23fooEi.arch_ivybridge -// LINUX: ret ptr @_ZN2S23fooEi.sse4.2 -// LINUX: ret ptr @_ZN2S23fooEi +// ITANIUM: define weak_odr ptr @_ZN2S23fooEi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN2S23fooEi.arch_sandybridge +// ITANIUM: ret ptr @_ZN2S23fooEi.arch_ivybridge +// ITANIUM: ret ptr @_ZN2S23fooEi.sse4.2 +// ITANIUM: ret ptr @_ZN2S23fooEi // WINDOWS: define weak_odr dso_local i32 @"?foo@S2@@QEAAHH@Z.resolver"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.arch_sandybridge" @@ -137,27 +144,28 @@ int templ_use() { // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.sse4.2" // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z" -// LINUX: define{{.*}} i32 @_ZN2S23fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: define{{.*}} i32 @_ZN2S23fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: define{{.*}} i32 @_ZN2S23fooEi(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: define{{.*}} i32 @_ZN2S23fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: define{{.*}} i32 @_ZN2S23fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: define{{.*}} i32 @_ZN2S23fooEi(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z.sse4.2"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z.arch_ivybridge"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z"(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: define{{.*}} i32 @_Z9templ_usev() -// LINUX: call noundef i32 @_ZN5templIiE3fooEi.ifunc -// LINUX: call noundef i32 @_ZN5templIdE3fooEi.ifunc +// ITANIUM: define{{.*}} i32 @_Z9templ_usev() +// ITANIUM: call noundef i32 @_ZN5templIiE3fooEi.ifunc +// ITANIUM: call noundef i32 @_ZN5templIdE3fooEi.ifunc // WINDOWS: define dso_local noundef i32 @"?templ_use@@YAHXZ"() // WINDOWS: call noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.resolver" // WINDOWS: call noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver" -// LINUX: define weak_odr ptr @_ZN5templIiE3fooEi.resolver() comdat -// LINUX: ret ptr @_ZN5templIiE3fooEi.arch_sandybridge -// LINUX: ret ptr @_ZN5templIiE3fooEi.arch_ivybridge -// LINUX: ret ptr @_ZN5templIiE3fooEi.sse4.2 -// LINUX: ret ptr @_ZN5templIiE3fooEi +// ITANIUM: define weak_odr ptr @_ZN5templIiE3fooEi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN5templIiE3fooEi.arch_sandybridge +// ITANIUM: ret ptr @_ZN5templIiE3fooEi.arch_ivybridge +// ITANIUM: ret ptr @_ZN5templIiE3fooEi.sse4.2 +// ITANIUM: ret ptr @_ZN5templIiE3fooEi // WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.resolver"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge" @@ -165,11 +173,12 @@ int templ_use() { // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2" // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z" -// LINUX: define weak_odr ptr @_ZN5templIdE3fooEi.resolver() comdat -// LINUX: ret ptr @_ZN5templIdE3fooEi.arch_sandybridge -// LINUX: ret ptr @_ZN5templIdE3fooEi.arch_ivybridge -// LINUX: ret ptr @_ZN5templIdE3fooEi.sse4.2 -// LINUX: ret ptr @_ZN5templIdE3fooEi +// ITANIUM: define weak_odr ptr @_ZN5templIdE3fooEi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN5templIdE3fooEi.arch_sandybridge +// ITANIUM: ret ptr @_ZN5templIdE3fooEi.arch_ivybridge +// ITANIUM: ret ptr @_ZN5templIdE3fooEi.sse4.2 +// ITANIUM: ret ptr @_ZN5templIdE3fooEi // WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge" @@ -177,42 +186,42 @@ int templ_use() { // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z" -// LINUX: define linkonce_odr noundef i32 @_ZN1S3fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: ret i32 0 +// ITANIUM: define linkonce_odr noundef i32 @_ZN1S3fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: ret i32 0 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: ret i32 0 -// LINUX: declare noundef i32 @_ZN1S3fooEi.arch_sandybridge(ptr {{[^,]*}}, i32 noundef) +// ITANIUM: declare noundef i32 @_ZN1S3fooEi.arch_sandybridge(ptr {{[^,]*}}, i32 noundef) // WINDOWS: declare dso_local noundef i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr {{[^,]*}}, i32 noundef) -// LINUX: define linkonce_odr noundef i32 @_ZN1S3fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: ret i32 1 +// ITANIUM: define linkonce_odr noundef i32 @_ZN1S3fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: ret i32 1 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: ret i32 1 -// LINUX: define linkonce_odr noundef i32 @_ZN1S3fooEi(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: ret i32 2 +// ITANIUM: define linkonce_odr noundef i32 @_ZN1S3fooEi(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: ret i32 2 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: ret i32 2 -// LINUX: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.sse4.2 -// LINUX: declare noundef i32 @_ZN5templIiE3fooEi.arch_sandybridge -// LINUX: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.arch_ivybridge -// LINUX: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi +// ITANIUM: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.sse4.2 +// ITANIUM: declare noundef i32 @_ZN5templIiE3fooEi.arch_sandybridge +// ITANIUM: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.arch_ivybridge +// ITANIUM: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2" // WINDOWS: declare dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge" // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_ivybridge" // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z" -// LINUX: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.sse4.2 -// LINUX: declare noundef i32 @_ZN5templIdE3fooEi.arch_sandybridge -// LINUX: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.arch_ivybridge -// LINUX: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi +// ITANIUM: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.sse4.2 +// ITANIUM: declare noundef i32 @_ZN5templIdE3fooEi.arch_sandybridge +// ITANIUM: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.arch_ivybridge +// ITANIUM: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2" // WINDOWS: declare dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge" diff --git a/clang/test/CodeGenCXX/attr-target-mv-modules.cpp b/clang/test/CodeGenCXX/attr-target-mv-modules.cpp index c91cf71fc5f8d4fc8251d0d403d0ccf5a6768715..ac3cf7c4b611c52fc65d368f6266dbc7e1d9a832 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-modules.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-modules.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fmodules -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -fmodules -emit-llvm %s -o - | FileCheck %s #pragma clang module build A module A {} #pragma clang module contents diff --git a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp index dda7de08aed43ed532b6882ec12490d503366de9..3c56cad3af914a7d90e93c0198386014f39db741 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS struct S { int __attribute__((target("sse4.2"))) foo(int); @@ -16,39 +17,42 @@ int bar() { return s.foo(0); } -// LINUX: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN1S3fooEi.resolver +// DARWIN-NOT: comdat -// LINUX: define{{.*}} i32 @_ZN1S3fooEi(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: ret i32 2 +// ITANIUM: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN1S3fooEi.resolver + +// ITANIUM: define{{.*}} i32 @_ZN1S3fooEi(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: ret i32 2 // WINDOWS: define dso_local noundef i32 @"?foo@S@@QEAAHH@Z"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: ret i32 2 -// LINUX: define{{.*}} i32 @_ZN1S3fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: ret i32 0 +// ITANIUM: define{{.*}} i32 @_ZN1S3fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: ret i32 0 // WINDOWS: define dso_local noundef i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: ret i32 0 -// LINUX: define{{.*}} i32 @_ZN1S3fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0) -// LINUX: ret i32 1 +// ITANIUM: define{{.*}} i32 @_ZN1S3fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0) +// ITANIUM: ret i32 1 // WINDOWS: define dso_local noundef i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(ptr {{[^,]*}} %this, i32 noundef %0) // WINDOWS: ret i32 1 -// LINUX: define{{.*}} i32 @_Z3barv() -// LINUX: %s = alloca %struct.S, align 1 -// LINUX: %call = call noundef i32 @_ZN1S3fooEi.ifunc(ptr {{[^,]*}} %s, i32 noundef 0) +// ITANIUM: define{{.*}} i32 @_Z3barv() +// ITANIUM: %s = alloca %struct.S, align 1 +// ITANIUM: %call = call noundef i32 @_ZN1S3fooEi.ifunc(ptr {{[^,]*}} %s, i32 noundef 0) // WINDOWS: define dso_local noundef i32 @"?bar@@YAHXZ"() // WINDOWS: %s = alloca %struct.S, align 1 // WINDOWS: %call = call noundef i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr {{[^,]*}} %s, i32 noundef 0) -// LINUX: define weak_odr ptr @_ZN1S3fooEi.resolver() comdat -// LINUX: ret ptr @_ZN1S3fooEi.arch_sandybridge -// LINUX: ret ptr @_ZN1S3fooEi.arch_ivybridge -// LINUX: ret ptr @_ZN1S3fooEi.sse4.2 -// LINUX: ret ptr @_ZN1S3fooEi +// ITANIUM: define weak_odr ptr @_ZN1S3fooEi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_ZN1S3fooEi.arch_sandybridge +// ITANIUM: ret ptr @_ZN1S3fooEi.arch_ivybridge +// ITANIUM: ret ptr @_ZN1S3fooEi.sse4.2 +// ITANIUM: ret ptr @_ZN1S3fooEi // WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr %0, i32 %1) @@ -56,6 +60,6 @@ int bar() { // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z"(ptr %0, i32 %1) -// LINUX: declare noundef i32 @_ZN1S3fooEi.arch_sandybridge(ptr {{[^,]*}}, i32 noundef) +// ITANIUM: declare noundef i32 @_ZN1S3fooEi.arch_sandybridge(ptr {{[^,]*}}, i32 noundef) // WINDOWS: declare dso_local noundef i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr {{[^,]*}}, i32 noundef) diff --git a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp index 49a05e7485a5de1640f07863e327004dc68edac4..e30fbf4ef5027d733400b18abdd8deb42fa27077 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS int __attribute__((target("sse4.2"))) foo_overload(int) { return 0; } @@ -14,21 +15,23 @@ int bar2() { return foo_overload() + foo_overload(1); } -// LINUX: @_Z12foo_overloadv.ifunc = weak_odr ifunc i32 (), ptr @_Z12foo_overloadv.resolver -// LINUX: @_Z12foo_overloadi.ifunc = weak_odr ifunc i32 (i32), ptr @_Z12foo_overloadi.resolver +// DARWIN-NOT: comdat -// LINUX: define{{.*}} i32 @_Z12foo_overloadi.sse4.2(i32 noundef %0) -// LINUX: ret i32 0 -// LINUX: define{{.*}} i32 @_Z12foo_overloadi.arch_ivybridge(i32 noundef %0) -// LINUX: ret i32 1 -// LINUX: define{{.*}} i32 @_Z12foo_overloadi(i32 noundef %0) -// LINUX: ret i32 2 -// LINUX: define{{.*}} i32 @_Z12foo_overloadv.sse4.2() -// LINUX: ret i32 0 -// LINUX: define{{.*}} i32 @_Z12foo_overloadv.arch_ivybridge() -// LINUX: ret i32 1 -// LINUX: define{{.*}} i32 @_Z12foo_overloadv() -// LINUX: ret i32 2 +// ITANIUM: @_Z12foo_overloadv.ifunc = weak_odr ifunc i32 (), ptr @_Z12foo_overloadv.resolver +// ITANIUM: @_Z12foo_overloadi.ifunc = weak_odr ifunc i32 (i32), ptr @_Z12foo_overloadi.resolver + +// ITANIUM: define{{.*}} i32 @_Z12foo_overloadi.sse4.2(i32 noundef %0) +// ITANIUM: ret i32 0 +// ITANIUM: define{{.*}} i32 @_Z12foo_overloadi.arch_ivybridge(i32 noundef %0) +// ITANIUM: ret i32 1 +// ITANIUM: define{{.*}} i32 @_Z12foo_overloadi(i32 noundef %0) +// ITANIUM: ret i32 2 +// ITANIUM: define{{.*}} i32 @_Z12foo_overloadv.sse4.2() +// ITANIUM: ret i32 0 +// ITANIUM: define{{.*}} i32 @_Z12foo_overloadv.arch_ivybridge() +// ITANIUM: ret i32 1 +// ITANIUM: define{{.*}} i32 @_Z12foo_overloadv() +// ITANIUM: ret i32 2 // WINDOWS: define dso_local noundef i32 @"?foo_overload@@YAHH@Z.sse4.2"(i32 noundef %0) // WINDOWS: ret i32 0 @@ -43,19 +46,20 @@ int bar2() { // WINDOWS: define dso_local noundef i32 @"?foo_overload@@YAHXZ"() // WINDOWS: ret i32 2 -// LINUX: define{{.*}} i32 @_Z4bar2v() -// LINUX: call noundef i32 @_Z12foo_overloadv.ifunc() -// LINUX: call noundef i32 @_Z12foo_overloadi.ifunc(i32 noundef 1) +// ITANIUM: define{{.*}} i32 @_Z4bar2v() +// ITANIUM: call noundef i32 @_Z12foo_overloadv.ifunc() +// ITANIUM: call noundef i32 @_Z12foo_overloadi.ifunc(i32 noundef 1) // WINDOWS: define dso_local noundef i32 @"?bar2@@YAHXZ"() // WINDOWS: call noundef i32 @"?foo_overload@@YAHXZ.resolver"() // WINDOWS: call noundef i32 @"?foo_overload@@YAHH@Z.resolver"(i32 noundef 1) -// LINUX: define weak_odr ptr @_Z12foo_overloadv.resolver() comdat -// LINUX: ret ptr @_Z12foo_overloadv.arch_sandybridge -// LINUX: ret ptr @_Z12foo_overloadv.arch_ivybridge -// LINUX: ret ptr @_Z12foo_overloadv.sse4.2 -// LINUX: ret ptr @_Z12foo_overloadv +// ITANIUM: define weak_odr ptr @_Z12foo_overloadv.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_Z12foo_overloadv.arch_sandybridge +// ITANIUM: ret ptr @_Z12foo_overloadv.arch_ivybridge +// ITANIUM: ret ptr @_Z12foo_overloadv.sse4.2 +// ITANIUM: ret ptr @_Z12foo_overloadv // WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge" @@ -63,11 +67,12 @@ int bar2() { // WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2" // WINDOWS: call i32 @"?foo_overload@@YAHXZ" -// LINUX: define weak_odr ptr @_Z12foo_overloadi.resolver() comdat -// LINUX: ret ptr @_Z12foo_overloadi.arch_sandybridge -// LINUX: ret ptr @_Z12foo_overloadi.arch_ivybridge -// LINUX: ret ptr @_Z12foo_overloadi.sse4.2 -// LINUX: ret ptr @_Z12foo_overloadi +// ITANIUM: define weak_odr ptr @_Z12foo_overloadi.resolver() +// LINUX-SAME: comdat +// ITANIUM: ret ptr @_Z12foo_overloadi.arch_sandybridge +// ITANIUM: ret ptr @_Z12foo_overloadi.arch_ivybridge +// ITANIUM: ret ptr @_Z12foo_overloadi.sse4.2 +// ITANIUM: ret ptr @_Z12foo_overloadi // WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) comdat // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_sandybridge" @@ -75,8 +80,8 @@ int bar2() { // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.sse4.2" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z" -// LINUX: declare noundef i32 @_Z12foo_overloadv.arch_sandybridge() -// LINUX: declare noundef i32 @_Z12foo_overloadi.arch_sandybridge(i32 noundef) +// ITANIUM: declare noundef i32 @_Z12foo_overloadv.arch_sandybridge() +// ITANIUM: declare noundef i32 @_Z12foo_overloadi.arch_sandybridge(i32 noundef) // WINDOWS: declare dso_local noundef i32 @"?foo_overload@@YAHXZ.arch_sandybridge"() // WINDOWS: declare dso_local noundef i32 @"?foo_overload@@YAHH@Z.arch_sandybridge"(i32 noundef) diff --git a/clang/test/CodeGenCXX/externc-ifunc-resolver.cpp b/clang/test/CodeGenCXX/externc-ifunc-resolver.cpp index 0518a8dcc831dd425b4734df481f894c10c57c9f..be4453ae7eb08ce320c88fbfb840feb226b39721 100644 --- a/clang/test/CodeGenCXX/externc-ifunc-resolver.cpp +++ b/clang/test/CodeGenCXX/externc-ifunc-resolver.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-macosx -emit-llvm -o - %s | FileCheck %s extern "C" { __attribute__((used)) static void *resolve_foo() { return 0; } diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl index a70e224b81e4b74ab36f6e97cc5a7058b12b5cee..7ca78e60fb9c596dfe7ce56755fb33a0fa40c35c 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s RWBuffer Buffer1; RWBuffer > BufferArray[4]; @@ -16,9 +16,9 @@ void main() { } // CHECK: !hlsl.uavs = !{![[Single:[0-9]+]], ![[Array:[0-9]+]], ![[SingleAllocated:[0-9]+]], ![[ArrayAllocated:[0-9]+]], ![[SingleSpace:[0-9]+]], ![[ArraySpace:[0-9]+]]} -// CHECK-DAG: ![[Single]] = !{ptr @"?Buffer1@@3V?$RWBuffer@M@hlsl@@A", !"RWBuffer", i32 10, i1 false, i32 -1, i32 0} -// CHECK-DAG: ![[Array]] = !{ptr @"?BufferArray@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RWBuffer >", i32 10, i1 false, i32 -1, i32 0} -// CHECK-DAG: ![[SingleAllocated]] = !{ptr @"?Buffer2@@3V?$RWBuffer@M@hlsl@@A", !"RWBuffer", i32 10, i1 false, i32 3, i32 0} -// CHECK-DAG: ![[ArrayAllocated]] = !{ptr @"?BufferArray2@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RWBuffer >", i32 10, i1 false, i32 4, i32 0} -// CHECK-DAG: ![[SingleSpace]] = !{ptr @"?Buffer3@@3V?$RWBuffer@M@hlsl@@A", !"RWBuffer", i32 10, i1 false, i32 3, i32 1} -// CHECK-DAG: ![[ArraySpace]] = !{ptr @"?BufferArray3@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RWBuffer >", i32 10, i1 false, i32 4, i32 1} +// CHECK-DAG: ![[Single]] = !{ptr @"?Buffer1@@3V?$RWBuffer@M@hlsl@@A", i32 10, i32 9, i1 false, i32 -1, i32 0} +// CHECK-DAG: ![[Array]] = !{ptr @"?BufferArray@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", i32 10, i32 9, i1 false, i32 -1, i32 0} +// CHECK-DAG: ![[SingleAllocated]] = !{ptr @"?Buffer2@@3V?$RWBuffer@M@hlsl@@A", i32 10, i32 9, i1 false, i32 3, i32 0} +// CHECK-DAG: ![[ArrayAllocated]] = !{ptr @"?BufferArray2@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", i32 10, i32 9, i1 false, i32 4, i32 0} +// CHECK-DAG: ![[SingleSpace]] = !{ptr @"?Buffer3@@3V?$RWBuffer@M@hlsl@@A", i32 10, i32 9, i1 false, i32 3, i32 1} +// CHECK-DAG: ![[ArraySpace]] = !{ptr @"?BufferArray3@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", i32 10, i32 9, i1 false, i32 4, i32 1} diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..87002ccd462d3f2c4ed086bcb1d2a7ccbf2e5599 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s + +RWBuffer BufI16; +RWBuffer BufU16; +RWBuffer BufI32; +RWBuffer BufU32; +RWBuffer BufI64; +RWBuffer BufU64; +RWBuffer BufF16; +RWBuffer BufF32; +RWBuffer BufF64; +RWBuffer< vector > BufI16x4; +RWBuffer< vector > BufU32x3; +RWBuffer BufF16x2; +RWBuffer BufF32x3; +// TODO: RWBuffer BufSNormF16; -> 11 +// TODO: RWBuffer BufUNormF16; -> 12 +// TODO: RWBuffer BufSNormF32; -> 13 +// TODO: RWBuffer BufUNormF32; -> 14 +// TODO: RWBuffer BufSNormF64; -> 15 +// TODO: RWBuffer BufUNormF64; -> 16 + +[numthreads(1,1,1)] +void main(int GI : SV_GroupIndex) { + BufI16[GI] = 0; + BufU16[GI] = 0; + BufI32[GI] = 0; + BufU32[GI] = 0; + BufI64[GI] = 0; + BufU64[GI] = 0; + BufF16[GI] = 0; + BufF32[GI] = 0; + BufF64[GI] = 0; + BufI16x4[GI] = 0; + BufU32x3[GI] = 0; + BufF16x2[GI] = 0; + BufF32x3[GI] = 0; +} + +// CHECK: !{{[0-9]+}} = !{ptr @"?BufI16@@3V?$RWBuffer@F@hlsl@@A", i32 10, i32 2, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufU16@@3V?$RWBuffer@G@hlsl@@A", i32 10, i32 3, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufI32@@3V?$RWBuffer@H@hlsl@@A", i32 10, i32 4, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufU32@@3V?$RWBuffer@I@hlsl@@A", i32 10, i32 5, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufI64@@3V?$RWBuffer@J@hlsl@@A", i32 10, i32 6, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufU64@@3V?$RWBuffer@K@hlsl@@A", i32 10, i32 7, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufF16@@3V?$RWBuffer@$f16@@hlsl@@A", i32 10, i32 8, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufF32@@3V?$RWBuffer@M@hlsl@@A", i32 10, i32 9, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufF64@@3V?$RWBuffer@N@hlsl@@A", i32 10, i32 10, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufI16x4@@3V?$RWBuffer@T?$__vector@F$03@__clang@@@hlsl@@A", i32 10, i32 2, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufU32x3@@3V?$RWBuffer@T?$__vector@I$02@__clang@@@hlsl@@A", i32 10, i32 5, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufF16x2@@3V?$RWBuffer@T?$__vector@$f16@$01@__clang@@@hlsl@@A", i32 10, i32 8, +// CHECK: !{{[0-9]+}} = !{ptr @"?BufF32x3@@3V?$RWBuffer@T?$__vector@M$02@__clang@@@hlsl@@A", i32 10, i32 9, diff --git a/clang/test/CodeGenHLSL/builtins/RasterizerOrderedBuffer-annotations.hlsl b/clang/test/CodeGenHLSL/builtins/RasterizerOrderedBuffer-annotations.hlsl index ce7d84ecf5b1470d1a6605bd9095b6f1e5130447..bf70cc2456c8bc1d12e2f630a2f9e5592315c772 100644 --- a/clang/test/CodeGenHLSL/builtins/RasterizerOrderedBuffer-annotations.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RasterizerOrderedBuffer-annotations.hlsl @@ -12,9 +12,9 @@ RasterizerOrderedBuffer > BufferArray3[4] : register(u4, space1 void main() {} // CHECK: !hlsl.uavs = !{![[Single:[0-9]+]], ![[Array:[0-9]+]], ![[SingleAllocated:[0-9]+]], ![[ArrayAllocated:[0-9]+]], ![[SingleSpace:[0-9]+]], ![[ArraySpace:[0-9]+]]} -// CHECK-DAG: ![[Single]] = !{ptr @"?Buffer1@@3V?$RasterizerOrderedBuffer@M@hlsl@@A", !"RasterizerOrderedBuffer", i32 10, i1 true, i32 -1, i32 0} -// CHECK-DAG: ![[Array]] = !{ptr @"?BufferArray@@3PAV?$RasterizerOrderedBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RasterizerOrderedBuffer >", i32 10, i1 true, i32 -1, i32 0} -// CHECK-DAG: ![[SingleAllocated]] = !{ptr @"?Buffer2@@3V?$RasterizerOrderedBuffer@M@hlsl@@A", !"RasterizerOrderedBuffer", i32 10, i1 true, i32 3, i32 0} -// CHECK-DAG: ![[ArrayAllocated]] = !{ptr @"?BufferArray2@@3PAV?$RasterizerOrderedBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RasterizerOrderedBuffer >", i32 10, i1 true, i32 4, i32 0} -// CHECK-DAG: ![[SingleSpace]] = !{ptr @"?Buffer3@@3V?$RasterizerOrderedBuffer@M@hlsl@@A", !"RasterizerOrderedBuffer", i32 10, i1 true, i32 3, i32 1} -// CHECK-DAG: ![[ArraySpace]] = !{ptr @"?BufferArray3@@3PAV?$RasterizerOrderedBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RasterizerOrderedBuffer >", i32 10, i1 true, i32 4, i32 1} +// CHECK-DAG: ![[Single]] = !{ptr @"?Buffer1@@3V?$RasterizerOrderedBuffer@M@hlsl@@A", i32 10, i32 9, i1 true, i32 -1, i32 0} +// CHECK-DAG: ![[Array]] = !{ptr @"?BufferArray@@3PAV?$RasterizerOrderedBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", i32 10, i32 9, i1 true, i32 -1, i32 0} +// CHECK-DAG: ![[SingleAllocated]] = !{ptr @"?Buffer2@@3V?$RasterizerOrderedBuffer@M@hlsl@@A", i32 10, i32 9, i1 true, i32 3, i32 0} +// CHECK-DAG: ![[ArrayAllocated]] = !{ptr @"?BufferArray2@@3PAV?$RasterizerOrderedBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", i32 10, i32 9, i1 true, i32 4, i32 0} +// CHECK-DAG: ![[SingleSpace]] = !{ptr @"?Buffer3@@3V?$RasterizerOrderedBuffer@M@hlsl@@A", i32 10, i32 9, i1 true, i32 3, i32 1} +// CHECK-DAG: ![[ArraySpace]] = !{ptr @"?BufferArray3@@3PAV?$RasterizerOrderedBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", i32 10, i32 9, i1 true, i32 4, i32 1} diff --git a/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl b/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl index 2e169ef60c70c4b966a4cff8f5f068ac98acc772..d560d4b945fea08d8b594a2903b154f53bb6c585 100644 --- a/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl @@ -85,7 +85,7 @@ float4 FillTwoPointFiveFloat(){ // CHECK: [[vec1Ptr:%.*]] = alloca <1 x float>, align 4 // CHECK: store <1 x float> , ptr [[vec1Ptr]], align 4 // CHECK: [[vec1:%.*]] = load <1 x float>, ptr [[vec1Ptr]], align 4 -// CHECK: [[vec1Ret:%.*]] = shufflevector <1 x float> [[vec1]], <1 x float> undef, <1 x i32> zeroinitializer +// CHECK: [[vec1Ret:%.*]] = shufflevector <1 x float> [[vec1]], <1 x float> poison, <1 x i32> zeroinitializer // CHECK: ret <1 x float> [[vec1Ret]] vector FillOneHalfFloat(){ return .5f.r; @@ -122,7 +122,7 @@ float2 HowManyFloats(float V) { // CHECK: [[XVec3:%.*]] = shufflevector <1 x double> [[XVec]], <1 x double> poison, <3 x i32> zeroinitializer // CHECK: [[XVal:%.*]] = extractelement <3 x double> [[XVec3]], i32 0 // CHECK: [[XValF:%.*]] = fptrunc double [[XVal]] to float -// CHECK: [[Vec3F1:%.*]] = insertelement <3 x float> undef, float [[XValF]], i32 0 +// CHECK: [[Vec3F1:%.*]] = insertelement <3 x float> poison, float [[XValF]], i32 0 // CHECK: store <1 x double> , ptr [[YTmp]], align 8 // CHECK: [[YVec:%.*]] = load <1 x double>, ptr [[YTmp]], align 8 diff --git a/clang/test/CodeGenHLSL/cbuf.hlsl b/clang/test/CodeGenHLSL/cbuf.hlsl index 5dee1feb902aa0391951d611a8afc75f7f7e7a08..dc2a6aaa8f433563135a2c78e1a7cc0afdeb8c2a 100644 --- a/clang/test/CodeGenHLSL/cbuf.hlsl +++ b/clang/test/CodeGenHLSL/cbuf.hlsl @@ -24,5 +24,5 @@ float foo() { // CHECK: !hlsl.cbufs = !{![[CBMD:[0-9]+]]} // CHECK: !hlsl.srvs = !{![[TBMD:[0-9]+]]} -// CHECK: ![[CBMD]] = !{ptr @[[CB]], !"A.cb.ty", i32 13, i1 false, i32 0, i32 2} -// CHECK: ![[TBMD]] = !{ptr @[[TB]], !"A.tb.ty", i32 15, i1 false, i32 2, i32 1} +// CHECK: ![[CBMD]] = !{ptr @[[CB]], i32 13, i32 0, i1 false, i32 0, i32 2} +// CHECK: ![[TBMD]] = !{ptr @[[TB]], i32 15, i32 0, i1 false, i32 2, i32 1} diff --git a/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl b/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl index a085c3dd70ebc214e8095364e148a539be3b483f..bb52f87615214bde649f9152be0aa19963e648f0 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s -O0 -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s -// CHECK: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8" +// CHECK: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" void foo(void) {} diff --git a/clang/test/CodeGenOpenCL/as_type.cl b/clang/test/CodeGenOpenCL/as_type.cl index d8e75db936f732a4856302faccacfe236c3afa3e..1fe26fbeafdb4b8717da8f7de859a377dd6f85c6 100644 --- a/clang/test/CodeGenOpenCL/as_type.cl +++ b/clang/test/CodeGenOpenCL/as_type.cl @@ -27,7 +27,7 @@ char3 f3(int x) { return __builtin_astype(x, char3); } -//CHECK: define{{.*}} spir_func <4 x i8> @f4(i32 noundef %[[x:.*]]) +//CHECK: define{{.*}} spir_func noundef <4 x i8> @f4(i32 noundef %[[x:.*]]) //CHECK: %[[astype:.*]] = bitcast i32 %[[x]] to <4 x i8> //CHECK-NOT: shufflevector //CHECK: ret <4 x i8> %[[astype]] @@ -43,7 +43,7 @@ int f5(char3 x) { return __builtin_astype(x, int); } -//CHECK: define{{.*}} spir_func i32 @f6(<4 x i8> noundef %[[x:.*]]) +//CHECK: define{{.*}} spir_func noundef i32 @f6(<4 x i8> noundef %[[x:.*]]) //CHECK: %[[astype:.*]] = bitcast <4 x i8> %[[x]] to i32 //CHECK-NOT: shufflevector //CHECK: ret i32 %[[astype]] @@ -51,7 +51,7 @@ int f6(char4 x) { return __builtin_astype(x, int); } -//CHECK: define{{.*}} spir_func <3 x i8> @f7(<3 x i8> noundef returned %[[x:.*]]) +//CHECK: define{{.*}} spir_func noundef <3 x i8> @f7(<3 x i8> noundef returned %[[x:.*]]) //CHECK-NOT: bitcast //CHECK-NOT: shufflevector //CHECK: ret <3 x i8> %[[x]] @@ -67,21 +67,21 @@ int3 f8(char16 x) { return __builtin_astype(x, int3); } -//CHECK: define{{.*}} spir_func ptr addrspace(1) @addr_cast(ptr noundef readnone %[[x:.*]]) +//CHECK: define{{.*}} spir_func noundef ptr addrspace(1) @addr_cast(ptr noundef readnone %[[x:.*]]) //CHECK: %[[cast:.*]] ={{.*}} addrspacecast ptr %[[x]] to ptr addrspace(1) //CHECK: ret ptr addrspace(1) %[[cast]] global int* addr_cast(int *x) { return __builtin_astype(x, global int*); } -//CHECK: define{{.*}} spir_func ptr addrspace(1) @int_to_ptr(i32 noundef %[[x:.*]]) +//CHECK: define{{.*}} spir_func noundef ptr addrspace(1) @int_to_ptr(i32 noundef %[[x:.*]]) //CHECK: %[[cast:.*]] = inttoptr i32 %[[x]] to ptr addrspace(1) //CHECK: ret ptr addrspace(1) %[[cast]] global int* int_to_ptr(int x) { return __builtin_astype(x, global int*); } -//CHECK: define{{.*}} spir_func i32 @ptr_to_int(ptr noundef %[[x:.*]]) +//CHECK: define{{.*}} spir_func noundef i32 @ptr_to_int(ptr noundef %[[x:.*]]) //CHECK: %[[cast:.*]] = ptrtoint ptr %[[x]] to i32 //CHECK: ret i32 %[[cast]] int ptr_to_int(int *x) { diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12-err.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12-err.cl new file mode 100644 index 0000000000000000000000000000000000000000..5e0153c42825e35decbc4ddf6458923aae107c88 --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12-err.cl @@ -0,0 +1,24 @@ +// REQUIRES: amdgpu-registered-target + +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1200 -verify -S -emit-llvm -o - %s + +kernel void builtins_amdgcn_s_barrier_signal_err(global int* in, global int* out, int barrier) { + + __builtin_amdgcn_s_barrier_signal(barrier); // expected-error {{'__builtin_amdgcn_s_barrier_signal' must be a constant integer}} + __builtin_amdgcn_s_barrier_wait(-1); + *out = *in; +} + +kernel void builtins_amdgcn_s_barrier_wait_err(global int* in, global int* out, int barrier) { + + __builtin_amdgcn_s_barrier_signal(-1); + __builtin_amdgcn_s_barrier_wait(barrier); // expected-error {{'__builtin_amdgcn_s_barrier_wait' must be a constant integer}} + *out = *in; +} + +kernel void builtins_amdgcn_s_barrier_signal_isfirst_err(global int* in, global int* out, int barrier) { + + __builtin_amdgcn_s_barrier_signal_isfirst(barrier); // expected-error {{'__builtin_amdgcn_s_barrier_signal_isfirst' must be a constant integer}} + __builtin_amdgcn_s_barrier_wait(-1); + *out = *in; +} diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl new file mode 100644 index 0000000000000000000000000000000000000000..2899d9e5c28898ee04be97f7f0bcaf01b8417670 --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl @@ -0,0 +1,222 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -cl-std=CL2.0 -O0 -triple amdgcn-unknown-unknown -target-cpu gfx1200 -S -emit-llvm -o - %s | FileCheck %s + +// REQUIRES: amdgpu-registered-target + +typedef unsigned int uint; + +// CHECK-LABEL: @test_permlane16_var( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store ptr addrspace(1) [[OUT:%.*]], ptr addrspace(5) [[OUT_ADDR]], align 8 +// CHECK-NEXT: store i32 [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: store i32 [[B:%.*]], ptr addrspace(5) [[B_ADDR]], align 4 +// CHECK-NEXT: store i32 [[C:%.*]], ptr addrspace(5) [[C_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(5) [[B_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(5) [[C_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.amdgcn.permlane16.var(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i1 false, i1 false) +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[OUT_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(1) [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +void test_permlane16_var(global uint* out, uint a, uint b, uint c) { + *out = __builtin_amdgcn_permlane16_var(a, b, c, 0, 0); +} + +// CHECK-LABEL: @test_permlanex16_var( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store ptr addrspace(1) [[OUT:%.*]], ptr addrspace(5) [[OUT_ADDR]], align 8 +// CHECK-NEXT: store i32 [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: store i32 [[B:%.*]], ptr addrspace(5) [[B_ADDR]], align 4 +// CHECK-NEXT: store i32 [[C:%.*]], ptr addrspace(5) [[C_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(5) [[B_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(5) [[C_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.amdgcn.permlanex16.var(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i1 false, i1 false) +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[OUT_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(1) [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +void test_permlanex16_var(global uint* out, uint a, uint b, uint c) { + *out = __builtin_amdgcn_permlanex16_var(a, b, c, 0, 0); +} + +// CHECK-LABEL: @test_s_barrier_signal( +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -1) +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -1) +// CHECK-NEXT: ret void +// +void test_s_barrier_signal() +{ + __builtin_amdgcn_s_barrier_signal(-1); + __builtin_amdgcn_s_barrier_wait(-1); +} + +// CHECK-LABEL: @test_s_barrier_signal_var( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store i32 [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.signal.var(i32 [[TMP0]]) +// CHECK-NEXT: ret void +// +void test_s_barrier_signal_var(int a) +{ + __builtin_amdgcn_s_barrier_signal_var(a); +} + +// CHECK-LABEL: @test_s_barrier_signal_isfirst( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: store ptr [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B:%.*]], ptr addrspace(5) [[B_ADDR]], align 8 +// CHECK-NEXT: store ptr [[C:%.*]], ptr addrspace(5) [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 1) +// CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +// CHECK: if.then: +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr addrspace(5) [[B_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP1]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: br label [[IF_END:%.*]] +// CHECK: if.else: +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr addrspace(5) [[C_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP2]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: br label [[IF_END]] +// CHECK: if.end: +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 1) +// CHECK-NEXT: ret void +// +void test_s_barrier_signal_isfirst(int* a, int* b, int *c) +{ + if(__builtin_amdgcn_s_barrier_signal_isfirst(1)) + a = b; + else + a = c; + + __builtin_amdgcn_s_barrier_wait(1); +} + +// CHECK-LABEL: @test_s_barrier_isfirst_var( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[D_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store ptr [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B:%.*]], ptr addrspace(5) [[B_ADDR]], align 8 +// CHECK-NEXT: store ptr [[C:%.*]], ptr addrspace(5) [[C_ADDR]], align 8 +// CHECK-NEXT: store i32 [[D:%.*]], ptr addrspace(5) [[D_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[D_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst.var(i32 [[TMP0]]) +// CHECK-NEXT: br i1 [[TMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +// CHECK: if.then: +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr addrspace(5) [[B_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP2]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: br label [[IF_END:%.*]] +// CHECK: if.else: +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr addrspace(5) [[C_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP3]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: br label [[IF_END]] +// CHECK: if.end: +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 1) +// CHECK-NEXT: ret void +// +void test_s_barrier_isfirst_var(int* a, int* b, int *c, int d) +{ + if ( __builtin_amdgcn_s_barrier_signal_isfirst_var(d)) + a = b; + else + a = c; + + __builtin_amdgcn_s_barrier_wait(1); + +} + +// CHECK-LABEL: @test_s_barrier_init( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store i32 [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.init(i32 1, i32 [[TMP0]]) +// CHECK-NEXT: ret void +// +void test_s_barrier_init(int a) +{ + __builtin_amdgcn_s_barrier_init(1, a); +} + +// CHECK-LABEL: @test_s_barrier_join( +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.join(i32 1) +// CHECK-NEXT: ret void +// +void test_s_barrier_join() +{ + __builtin_amdgcn_s_barrier_join(1); +} + +// CHECK-LABEL: @test_s_wakeup_barrier( +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.amdgcn.s.barrier.join(i32 1) +// CHECK-NEXT: ret void +// +void test_s_wakeup_barrier() +{ + __builtin_amdgcn_s_barrier_join(1); +} + +// CHECK-LABEL: @test_s_barrier_leave( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: store ptr [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B:%.*]], ptr addrspace(5) [[B_ADDR]], align 8 +// CHECK-NEXT: store ptr [[C:%.*]], ptr addrspace(5) [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call i1 @llvm.amdgcn.s.barrier.leave() +// CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +// CHECK: if.then: +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr addrspace(5) [[B_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP1]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: br label [[IF_END:%.*]] +// CHECK: if.else: +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr addrspace(5) [[C_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP2]], ptr addrspace(5) [[A_ADDR]], align 8 +// CHECK-NEXT: br label [[IF_END]] +// CHECK: if.end: +// CHECK-NEXT: ret void +// +void test_s_barrier_leave(int* a, int* b, int *c) +{ + if (__builtin_amdgcn_s_barrier_leave()) + a = b; + else + a = c; +} + +// CHECK-LABEL: @test_s_get_barrier_state( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[STATE:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: store i32 [[A:%.*]], ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.amdgcn.s.get.barrier.state(i32 [[TMP0]]) +// CHECK-NEXT: store i32 [[TMP1]], ptr addrspace(5) [[STATE]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(5) [[STATE]], align 4 +// CHECK-NEXT: ret i32 [[TMP2]] +// +unsigned test_s_get_barrier_state(int a) +{ + unsigned State = __builtin_amdgcn_s_get_barrier_state(a); + return State; +} diff --git a/clang/test/CodeGenOpenCL/partial_initializer.cl b/clang/test/CodeGenOpenCL/partial_initializer.cl index cfdacd150e046e823b85c3a92ec3b9f48caa70da..5cc4e2b246003a101f5e91eb1574377d05bf62e7 100644 --- a/clang/test/CodeGenOpenCL/partial_initializer.cl +++ b/clang/test/CodeGenOpenCL/partial_initializer.cl @@ -49,7 +49,7 @@ void f(void) { // CHECK: store <2 x i32> , ptr %[[compoundliteral1]], align 8 // CHECK: %[[v6:.*]] = load <2 x i32>, ptr %[[compoundliteral1]], align 8 // CHECK: %[[vext:.*]] = shufflevector <2 x i32> %[[v6]], <2 x i32> poison, <4 x i32> - // CHECK: %[[vecinit:.*]] = shufflevector <4 x i32> %[[vext]], <4 x i32> undef, <4 x i32> + // CHECK: %[[vecinit:.*]] = shufflevector <4 x i32> %[[vext]], <4 x i32> poison, <4 x i32> // CHECK: %[[vecinit2:.*]] = insertelement <4 x i32> %[[vecinit]], i32 3, i32 2 // CHECK: %[[vecinit3:.*]] = insertelement <4 x i32> %[[vecinit2]], i32 4, i32 3 // CHECK: store <4 x i32> %[[vecinit3]], ptr %[[compoundliteral]], align 16 diff --git a/clang/test/CodeGenOpenCL/vector_literals.cl b/clang/test/CodeGenOpenCL/vector_literals.cl index 6fbe38310db3142059d3dba665390eff250645fe..f69f339ca99aaf4c4d493cb23a47a3ccaf700c37 100644 --- a/clang/test/CodeGenOpenCL/vector_literals.cl +++ b/clang/test/CodeGenOpenCL/vector_literals.cl @@ -14,38 +14,38 @@ __constant const int4 c2 = (int4)(1, 2, ((int2)(3, 4))); // CHECK: constant <4 x i32> void vector_literals_valid() { - //CHECK: insertelement <4 x i32> , i32 %{{.+}}, i32 2 + //CHECK: insertelement <4 x i32> , i32 %{{.+}}, i32 2 //CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 3 int4 a_1_1_1_1 = (int4)(1, 2, c1.s2, c2.s3); //CHECK: store <2 x i32> , ptr //CHECK: shufflevector <2 x i32> %{{[0-9]+}}, <2 x i32> poison, <4 x i32> - //CHECK: shufflevector <4 x i32> %{{.+}}, <4 x i32> undef, <4 x i32> + //CHECK: shufflevector <4 x i32> %{{.+}}, <4 x i32> poison, <4 x i32> //CHECK: insertelement <4 x i32> %{{.+}}, i32 3, i32 2 //CHECK: insertelement <4 x i32> %{{.+}}, i32 4, i32 3 int4 a_2_1_1 = (int4)((int2)(1, 2), 3, 4); //CHECK: store <2 x i32> , ptr //CHECK: shufflevector <2 x i32> %{{[0-9]+}}, <2 x i32> poison, <4 x i32> - //CHECK: shufflevector <4 x i32> , <4 x i32> %{{.+}}, <4 x i32> + //CHECK: shufflevector <4 x i32> , <4 x i32> %{{.+}}, <4 x i32> //CHECK: insertelement <4 x i32> %{{.+}}, i32 4, i32 3 int4 a_1_2_1 = (int4)(1, (int2)(2, 3), 4); //CHECK: store <2 x i32> , ptr //CHECK: shufflevector <2 x i32> %{{[0-9]+}}, <2 x i32> poison, <4 x i32> - //CHECK: shufflevector <4 x i32> , <4 x i32> %{{.+}}, <4 x i32> + //CHECK: shufflevector <4 x i32> , <4 x i32> %{{.+}}, <4 x i32> int4 a_1_1_2 = (int4)(1, 2, (int2)(3, 4)); //CHECK: store <2 x i32> , ptr //CHECK: shufflevector <2 x i32> %{{[0-9]+}}, <2 x i32> poison, <4 x i32> - //CHECK: shufflevector <4 x i32> %{{.+}}, <4 x i32> undef, <4 x i32> + //CHECK: shufflevector <4 x i32> %{{.+}}, <4 x i32> poison, <4 x i32> //CHECK: shufflevector <4 x i32> %{{.+}}, <4 x i32> , <4 x i32> int4 a_2_2 = (int4)((int2)(1, 2), (int2)(3)); //CHECK: store <4 x i32> , ptr //CHECK: shufflevector <4 x i32> %{{.+}}, <4 x i32> poison, <3 x i32> //CHECK: shufflevector <3 x i32> %{{.+}}, <3 x i32> poison, <4 x i32> - //CHECK: shufflevector <4 x i32> , <4 x i32> %{{.+}}, <4 x i32> + //CHECK: shufflevector <4 x i32> , <4 x i32> %{{.+}}, <4 x i32> int4 a_1_3 = (int4)(1, (int3)(2, 3, 4)); //CHECK: store <4 x i32> , ptr %a @@ -54,7 +54,7 @@ void vector_literals_valid() { //CHECK: load <4 x i32>, ptr %a //CHECK: shufflevector <4 x i32> %{{[0-9]+}}, <4 x i32> poison, <2 x i32> //CHECK: shufflevector <2 x i32> %{{[0-9]+}}, <2 x i32> poison, <8 x i32> - //CHECK: shufflevector <8 x i32> , <8 x i32> %{{.+}}, <8 x i32> + //CHECK: shufflevector <8 x i32> , <8 x i32> %{{.+}}, <8 x i32> //CHECK: load <4 x i32>, ptr %a //CHECK: shufflevector <4 x i32> %{{[0-9]+}}, <4 x i32> poison, <8 x i32> //CHECK: shufflevector <8 x i32> %{{.+}}, <8 x i32> %{{.+}}, <8 x i32> diff --git a/clang/test/CodeGenOpenCL/vector_shufflevector.cl b/clang/test/CodeGenOpenCL/vector_shufflevector.cl index a7018ca908f40e039dbc97406dc2d24dbec28f42..7fe113e06c83f7c29f635a896235c3c75ea82e29 100644 --- a/clang/test/CodeGenOpenCL/vector_shufflevector.cl +++ b/clang/test/CodeGenOpenCL/vector_shufflevector.cl @@ -8,6 +8,6 @@ typedef unsigned int uint2 __attribute((ext_vector_type(2))); void vector_shufflevector_valid(void) { - //CHECK: {{%.*}} = shufflevector <2 x i32> {{%.*}}, <2 x i32> undef, <2 x i32> + //CHECK: {{%.*}} = shufflevector <2 x i32> {{%.*}}, <2 x i32> poison, <2 x i32> (uint2)(((uint2)(0)).s0, 0); } diff --git a/clang/test/Driver/aarch64-pauth-lr.c b/clang/test/Driver/aarch64-pauth-lr.c new file mode 100644 index 0000000000000000000000000000000000000000..2e1b530fc9895b5278d59c685ae63a3464c1185e --- /dev/null +++ b/clang/test/Driver/aarch64-pauth-lr.c @@ -0,0 +1,23 @@ +// Check the -cc1 flags for the various forms of -mbranch-protection=pac-ret+pc. + +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+b-key 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-B-KEY +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+leaf 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-LEAF +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+bti 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-BTI +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+leaf+b-key+bti 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-LEAF-B-KEY-BTI +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc -march=armv9.5-a 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+b-key -march=armv9.5-a 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-B-KEY +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+leaf -march=armv9.5-a 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-LEAF +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+bti -march=armv9.5-a 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-BTI +// RUN: %clang -target aarch64-arm-none-eabi -c %s -### -mbranch-protection=pac-ret+pc+leaf+b-key+bti -march=armv9.5-a 2>&1 | FileCheck %s --check-prefixes=PAUTH-LR-LEAF-B-KEY-BTI + +// PAUTH-LR: "-msign-return-address=non-leaf" "-msign-return-address-key=a_key" "-mbranch-protection-pauth-lr" +// PAUTH-LR-B-KEY: "-msign-return-address=non-leaf" "-msign-return-address-key=b_key" "-mbranch-protection-pauth-lr" +// PAUTH-LR-LEAF: "-msign-return-address=all" "-msign-return-address-key=a_key" "-mbranch-protection-pauth-lr" +// PAUTH-LR-BTI: "-msign-return-address=non-leaf" "-msign-return-address-key=a_key" "-mbranch-protection-pauth-lr" +// PAUTH-LR-LEAF-B-KEY-BTI: "-msign-return-address=all" "-msign-return-address-key=b_key" "-mbranch-protection-pauth-lr" "-mbranch-target-enforce" + +// NOT-PAUTH-LR: "-mbranch-target-enforce" +// NOT-PAUTH-LR-B-KEY: "-mbranch-target-enforce" +// NOT-PAUTH-LR-LEAF: "-mbranch-target-enforce" +// NOT-PAUTH-LR-BTI: "-mbranch-target-enforce" diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c index 6044a4f155db02c4da40a903feeeb7fdc6540d4e..13069c04c8d1c8f87e4929055bd53e00aa4b9436 100644 --- a/clang/test/Driver/aarch64-v95a.c +++ b/clang/test/Driver/aarch64-v95a.c @@ -1,3 +1,5 @@ +// ===== Base v9.5a architecture ===== + // RUN: %clang -target aarch64 -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s // RUN: %clang -target aarch64 -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s // RUN: %clang -target aarch64 -mlittle-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s @@ -5,6 +7,7 @@ // RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s // RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s // GENERICV95A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" + // RUN: %clang -target aarch64_be -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s // RUN: %clang -target aarch64_be -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s // RUN: %clang -target aarch64 -mbig-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s @@ -13,3 +16,16 @@ // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s // GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" +// ===== Features supported on aarch64 ===== + +// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck -check-prefix=V95A-CPA %s +// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | FileCheck -check-prefix=V95A-CPA %s +// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+cpa" + +// RUN: %clang -target aarch64 -march=armv9.5a+pauth-lr -### -c %s 2>&1 | FileCheck -check-prefix=V95A-PAUTHLR %s +// RUN: %clang -target aarch64 -march=armv9.5-a+pauth-lr -### -c %s 2>&1 | FileCheck -check-prefix=V95A-PAUTHLR %s +// V95A-PAUTHLR: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+pauth-lr" + +// RUN: %clang -target aarch64 -march=armv9.5a+tlbiw -### -c %s 2>&1 | FileCheck -check-prefix=V95A-TLBIW %s +// RUN: %clang -target aarch64 -march=armv9.5-a+tlbiw -### -c %s 2>&1 | FileCheck -check-prefix=V95A-TLBIW %s +// V95A-TLBIW: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.5a" "-target-feature" "+tlbiw" diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 81d1b907eced188c5c7096aca6e9c751f9973eb3..5b6dfe308a76eae703bc216db2410369ae59e6d4 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -272,10 +272,12 @@ // RUN: not %clang_cl /vmg /vmm /vms -### -- %s 2>&1 | FileCheck -check-prefix=VMX %s // VMX: '/vms' not allowed with '/vmm' -// RUN: %clang_cl /volatile:iso -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-ISO %s +// RUN: %clang_cl --target=i686-pc-win32 /volatile:iso -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-ISO %s +// RUN: %clang_cl --target=aarch64-pc-win32 -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-ISO %s // VOLATILE-ISO-NOT: "-fms-volatile" -// RUN: %clang_cl /volatile:ms -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-MS %s +// RUN: %clang_cl --target=aarch64-pc-win32 /volatile:ms -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-MS %s +// RUN: %clang_cl --target=i686-pc-win32 -### -- %s 2>&1 | FileCheck -check-prefix=VOLATILE-MS %s // VOLATILE-MS: "-fms-volatile" // RUN: %clang_cl /W0 -### -- %s 2>&1 | FileCheck -check-prefix=W0 %s diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index ebe8a0520bf0fca399484e2391896a9d74161683..c8b44e056e58f76fe433fcc3176fc49c1831c4b6 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -611,3 +611,9 @@ // CHECK-INT-OBJEMITTER-NOT: unsupported option '-fintegrated-objemitter' for target // RUN: not %clang -### -fno-integrated-objemitter --target=x86_64 %s 2>&1 | FileCheck -check-prefix=CHECK-NOINT-OBJEMITTER %s // CHECK-NOINT-OBJEMITTER: unsupported option '-fno-integrated-objemitter' for target + +// RUN: %clang -### --target=aarch64-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s +// RUN: %clang -### --target=aarch64-windows-msvc -fms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-MS-VOLATILE %s +// RUN: %clang -### --target=aarch64-windows-msvc -fno-ms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s +// CHECK-MS-VOLATILE: -fms-volatile +// CHECK-NO-MS-VOLATILE-NOT: -fms-volatile diff --git a/clang/test/Driver/darwin-builtin-modules.c b/clang/test/Driver/darwin-builtin-modules.c index 215f2b8d2c142ac66c34a42bffef7cdf2b8bfd91..1c56e13bfb9293b438b601e791b82180b4210059 100644 --- a/clang/test/Driver/darwin-builtin-modules.c +++ b/clang/test/Driver/darwin-builtin-modules.c @@ -9,19 +9,3 @@ // RUN: %clang -isysroot %S/Inputs/MacOSX99.0.sdk -target x86_64-apple-macos98.0 -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s // RUN: %clang -isysroot %S/Inputs/MacOSX99.0.sdk -target x86_64-apple-macos99.0 -### %s 2>&1 | FileCheck --check-prefix=CHECK_FUTURE %s // CHECK_FUTURE-NOT: -fbuiltin-headers-in-system-modules - - -// Check that builtin_headers_in_system_modules is only set if -fbuiltin-headers-in-system-modules and -fmodules are both set. - -// RUN: %clang -isysroot %S/Inputs/iPhoneOS13.0.sdk -target arm64-apple-ios13.0 -fsyntax-only %s -Xclang -verify=no-feature -// RUN: %clang -isysroot %S/Inputs/iPhoneOS13.0.sdk -target arm64-apple-ios13.0 -fsyntax-only %s -fmodules -Xclang -verify=yes-feature -// RUN: %clang -isysroot %S/Inputs/MacOSX99.0.sdk -target x86_64-apple-macos99.0 -fsyntax-only %s -Xclang -verify=no-feature -// RUN: %clang -isysroot %S/Inputs/MacOSX99.0.sdk -target x86_64-apple-macos99.0 -fsyntax-only %s -fmodules -Xclang -verify=no-feature - -#if __has_feature(builtin_headers_in_system_modules) -#error "has builtin_headers_in_system_modules" -// yes-feature-error@-1 {{}} -#else -#error "no builtin_headers_in_system_modules" -// no-feature-error@-1 {{}} -#endif diff --git a/clang/test/Driver/fbasic-block-sections.c b/clang/test/Driver/fbasic-block-sections.c index 417cf9b6319bde97ff34ba73ac5968d472e99b97..24262209d1e4d51426f4a994c3f3b2d78d096852 100644 --- a/clang/test/Driver/fbasic-block-sections.c +++ b/clang/test/Driver/fbasic-block-sections.c @@ -1,15 +1,15 @@ -// RUN: %clang -### -target x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s -// RUN: %clang -### -target x86_64 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-ALL %s -// RUN: %clang -### -target x86_64 -fbasic-block-sections=list=%s %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LIST %s -// RUN: %clang -### -target x86_64 -fbasic-block-sections=labels %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LABELS %s -// RUN: not %clang -c -target arm-unknown-linux -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s -// RUN: %clang -### -target arm-unknown-linux -fbasic-block-sections=all -fbasic-block-sections=none %s -S 2>&1 \ +// RUN: %clang -### --target=x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s +// RUN: %clang -### --target=x86_64 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-ALL %s +// RUN: %clang -### --target=x86_64 -fbasic-block-sections=list=%s %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LIST %s +// RUN: %clang -### --target=x86_64 -fbasic-block-sections=labels %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LABELS %s +// RUN: not %clang -c --target=arm-unknown-linux -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s +// RUN: %clang -### --target=arm-unknown-linux -fbasic-block-sections=all -fbasic-block-sections=none %s -S 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-NOOPT %s -// RUN: not %clang -c -target x86_64-apple-darwin10 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s -// RUN: not %clang -### -target x86_64 -fbasic-block-sections=alll %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s -// RUN: not %clang -### -target x86_64 -fbasic-block-sections=list %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s -// RUN: %clang -### -target x86_64 -fbasic-block-sections=list= %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NULL-LIST %s -// RUN: %clang -### -target x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s +// RUN: not %clang -c --target=x86_64-apple-darwin10 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s +// RUN: not %clang -### --target=x86_64 -fbasic-block-sections=alll %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s +// RUN: not %clang -### --target=x86_64 -fbasic-block-sections=list %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s +// RUN: %clang -### --target=x86_64 -fbasic-block-sections=list= %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NULL-LIST %s +// RUN: %clang -### --target=x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s // RUN: %clang -### -x cuda -nocudainc -nocudalib --target=x86_64 -fbasic-block-sections=all --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s -c 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-CUDA %s diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c index b763a003452ba721cff3bb7248caa833ef6cf3dd..e51c5ea381d31ae76367502c790ebc0e95932a69 100644 --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -49,10 +49,12 @@ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out +// RUN: llvm-ar rcs %t.a %t.o // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ -// RUN: --linker-path=/usr/bin/ld.lld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CPU-LINK +// RUN: --linker-path=/usr/bin/ld.lld -- --whole-archive %t.a --no-whole-archive \ +// RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CPU-LINK -// CPU-LINK: clang{{.*}} -o {{.*}}.img --target=x86_64-unknown-linux-gnu -march=native -O2 -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared +// CPU-LINK: clang{{.*}} -o {{.*}}.img --target=x86_64-unknown-linux-gnu -march=native -O2 -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -mllvm -openmp-opt-disable \ diff --git a/clang/test/Driver/modules.m b/clang/test/Driver/modules.m index 9eb3569805569ae1c55b93f84ba691acd5e10980..d1a65f5cb07133a21117cc800027801989bc88e1 100644 --- a/clang/test/Driver/modules.m +++ b/clang/test/Driver/modules.m @@ -57,7 +57,21 @@ // CHECK-MODULE-MAP-FILES: "-fmodule-map-file=foo.map" // CHECK-MODULE-MAP-FILES: "-fmodule-map-file=bar.map" -// RUN: %clang -fmodules -fbuiltin-module-map -### %s 2>&1 | FileCheck -check-prefix=CHECK-BUILTIN-MODULE-MAP %s +// Verify that the driver propagates -fmodule-name and -fmodule-map-file flags when +// -fmodules-decluse or -fmodules-strict-decluse, as used for layering check. +// RUN: %clang -fmodules-decluse -fmodule-name=foo -c -### %s 2>&1 | FileCheck -check-prefix=CHECK-DECLUSE-PROPAGATE-MODULE-NAME %s +// CHECK-DECLUSE-PROPAGATE-MODULE-NAME: -fmodule-name=foo + +// RUN: %clang -fmodules-decluse -fmodule-map-file=foo.map -c -### %s 2>&1 | FileCheck -check-prefix=CHECK-DECLUSE-PROPAGATE-MODULE-MAPS %s +// CHECK-DECLUSE-PROPAGATE-MODULE-MAPS: -fmodule-map-file=foo.map + +// RUN: %clang -fmodules-strict-decluse -fmodule-name=foo -c -### %s 2>&1 | FileCheck -check-prefix=CHECK-STRICT-DECLUSE-PROPAGATE-MODULE-NAME %s +// CHECK-STRICT-DECLUSE-PROPAGATE-MODULE-NAME: -fmodule-name=foo + +// RUN: %clang -fmodules-strict-decluse -fmodule-map-file=foo.map -c -### %s 2>&1 | FileCheck -check-prefix=CHECK-STRICT-DECLUSE-PROPAGATE-MODULE-MAPS %s +// CHECK-STRICT-DECLUSE-PROPAGATE-MODULE-MAPS: -fmodule-map-file=foo.map + + // RUN: %clang -fmodules -fbuiltin-module-map -### %s 2>&1 | FileCheck -check-prefix=CHECK-BUILTIN-MODULE-MAP %s // CHECK-BUILTIN-MODULE-MAP: "-fmodules" // CHECK-BUILTIN-MODULE-MAP: "-fmodule-map-file={{.*}}include{{/|\\\\}}module.modulemap" diff --git a/clang/test/Driver/riscv-abi.c b/clang/test/Driver/riscv-abi.c index e67f790e0de0e599731c5f856e16206b99f88dec..16568271564c7978307afdec182385b53021c88e 100644 --- a/clang/test/Driver/riscv-abi.c +++ b/clang/test/Driver/riscv-abi.c @@ -4,8 +4,6 @@ // RUN: | FileCheck -check-prefix=CHECK-ILP32 %s // RUN: %clang --target=riscv32-unknown-elf %s -### -march=rv32imc 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ILP32 %s -// RUN: %clang --target=riscv32-unknown-elf %s -### -march=rv32imf 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-ILP32 %s // RUN: %clang --target=riscv32-unknown-elf -x assembler %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ILP32 %s // RUN: %clang --target=riscv32-unknown-elf -x assembler %s -### \ @@ -24,6 +22,10 @@ // RUN: %clang --target=riscv32-unknown-elf %s -### -march=rv32if -mabi=ilp32f 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ILP32F %s +// RUN: %clang --target=riscv32-unknown-elf %s -### -mabi=ilp32f 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-ILP32F %s +// RUN: %clang --target=riscv32-unknown-elf %s -### -march=rv32if 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-ILP32F %s // CHECK-ILP32F: "-target-abi" "ilp32f" @@ -51,8 +53,6 @@ // RUN: | FileCheck -check-prefix=CHECK-LP64 %s // RUN: %clang --target=riscv64-unknown-elf %s -### -march=rv64imc 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-LP64 %s -// RUN: %clang --target=riscv64-unknown-elf %s -### -march=rv64imf 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-LP64 %s // RUN: %clang --target=riscv64-unknown-elf -x assembler %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-LP64 %s // RUN: %clang --target=riscv64-unknown-elf -x assembler %s -### \ @@ -60,7 +60,11 @@ // CHECK-LP64: "-target-abi" "lp64" -// RUN: not %clang --target=riscv64-unknown-elf %s -### -march=rv64f -mabi=lp64f 2>&1 \ +// RUN: %clang --target=riscv64-unknown-elf %s -### -march=rv64if -mabi=lp64f 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-LP64F %s +// RUN: %clang --target=riscv64-unknown-elf %s -### -mabi=lp64f 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-LP64F %s +// RUN: %clang --target=riscv64-unknown-elf %s -### -march=rv64if 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-LP64F %s // CHECK-LP64F: "-target-abi" "lp64f" diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c index 6c31282d0c8d49c2f52b0912a439cb8a9f51f1a6..d181755bb585070f61c50fcb028a6cdc1a2708f4 100644 --- a/clang/test/Driver/riscv-cpus.c +++ b/clang/test/Driver/riscv-cpus.c @@ -113,7 +113,7 @@ // MCPU-SIFIVE-E24: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" // MCPU-SIFIVE-E24: "-target-feature" "+c" // MCPU-SIFIVE-E24: "-target-feature" "+zicsr" "-target-feature" "+zifencei" -// MCPU-SIFIVE-E24: "-target-abi" "ilp32" +// MCPU-SIFIVE-E24: "-target-abi" "ilp32f" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e34 | FileCheck -check-prefix=MCPU-SIFIVE-E34 %s @@ -121,7 +121,7 @@ // MCPU-SIFIVE-E34: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" // MCPU-SIFIVE-E34: "-target-feature" "+c" // MCPU-SIFIVE-E34: "-target-feature" "+zicsr" "-target-feature" "+zifencei" -// MCPU-SIFIVE-E34: "-target-abi" "ilp32" +// MCPU-SIFIVE-E34: "-target-abi" "ilp32f" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s21 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-S21 %s @@ -153,7 +153,6 @@ // MCPU-SIFIVE-S76: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d" // MCPU-SIFIVE-S76: "-target-feature" "+c" // MCPU-SIFIVE-S76: "-target-feature" "+zicsr" "-target-feature" "+zifencei" "-target-feature" "+zihintpause" -// MCPU-SIFIVE-S76: "-target-feature" "+xsfcie" // MCPU-SIFIVE-S76: "-target-abi" "lp64d" // mcpu with default march @@ -178,7 +177,7 @@ // MCPU-SIFIVE-E76: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" // MCPU-SIFIVE-E76: "-target-feature" "+c" // MCPU-SIFIVE-E76: "-target-feature" "+zicsr" "-target-feature" "+zifencei" -// MCPU-SIFIVE-E76: "-target-abi" "ilp32" +// MCPU-SIFIVE-E76: "-target-abi" "ilp32f" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u74 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-U74 %s @@ -222,6 +221,27 @@ // MCPU-SIFIVE-X280-SAME: "-target-feature" "+zvl512b" "-target-feature" "+zvl64b" // MCPU-SIFIVE-X280-SAME: "-target-abi" "lp64d" +// RUN: %clang -target riscv64 -### -c %s 2>&1 -mcpu=sifive-p450 | FileCheck -check-prefix=MCPU-SIFIVE-P450 %s +// MCPU-SIFIVE-P450: "-nostdsysteminc" "-target-cpu" "sifive-p450" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+m" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+a" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+f" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+d" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+c" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zicbom" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zicbop" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zicboz" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zicsr" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zifencei" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zihintntl" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zihintpause" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zihpm" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zfhmin" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zba" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zbb" +// MCPU-SIFIVE-P450-SAME: "-target-feature" "+zbs" +// MCPU-SIFIVE-P450-SAME: "-target-abi" "lp64d" +// // Check failed cases // RUN: not %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv321 | FileCheck -check-prefix=FAIL-MCPU-NAME %s diff --git a/clang/test/Driver/riscv-default-features.c b/clang/test/Driver/riscv-default-features.c index 6e48f7cc37dcb0e7eab2cc8bebec7fcd2871c3b5..4c3883c1cc1184d0ca65f651524d9905119fb337 100644 --- a/clang/test/Driver/riscv-default-features.c +++ b/clang/test/Driver/riscv-default-features.c @@ -2,9 +2,7 @@ // RUN: %clang --target=riscv64-unknown-elf -S -emit-llvm %s -o - | FileCheck %s -check-prefix=RV64 // RV32: "target-features"="+32bit,+a,+c,+m,+relax, -// RV32-SAME: -save-restore // RV64: "target-features"="+64bit,+a,+c,+m,+relax, -// RV64-SAME: -save-restore // Dummy function int foo(void){ diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c index 716f3f6da57b88918d81c00bc86454ad02dace2e..d3700f71aa7e1de011599f39f01bcc37d7293629 100644 --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -24,7 +24,7 @@ // SAVE-RESTORE: "-target-feature" "+save-restore" // NO-SAVE-RESTORE: "-target-feature" "-save-restore" -// DEFAULT: "-target-feature" "-save-restore" +// DEFAULT-NOT: "-target-feature" "-save-restore" // DEFAULT-NOT: "-target-feature" "+save-restore" // RUN: %clang --target=riscv32-unknown-elf -### %s -munaligned-access 2>&1 | FileCheck %s -check-prefix=FAST-UNALIGNED-ACCESS diff --git a/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c b/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c new file mode 100644 index 0000000000000000000000000000000000000000..1f8a5a8821edfadb551ddb7d3f6ff06ca5e59938 --- /dev/null +++ b/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c @@ -0,0 +1,81 @@ +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32imc -mabi=ilp32 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMC-ILP32 %s +// GCC-MULTI-LIB-REUSE-RV32IMC-ILP32: rv32im/ilp32 +// GCC-MULTI-LIB-REUSE-RV32IMC-ILP32-NOT: {{^.+$}} + +// Check rv32imac won't reuse rv32im or rv32ic +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32imac -mabi=ilp32 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32 %s +// GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32: rv32imac/ilp32 +// GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32--NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32iac -mabi=ilp32 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IAC-ILP32 %s +// GCC-MULTI-LIB-REUSE-RV32IAC-ILP32: rv32iac/ilp32 +// GCC-MULTI-LIB-REUSE-RV32IAC-ILP32-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32imafdc -mabi=ilp32f \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F %s +// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F: rv32imafc/ilp32f +// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32imafdc -mabi=ilp32d \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D %s +// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D: . +// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv64imafc -mabi=lp64 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64 %s +// GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64: rv64imac/lp64 +// GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32imafc_zfh -mabi=ilp32 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32 %s +// GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32: rv32imac/ilp32 +// GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv32i_zvkb -mabi=ilp32 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32 %s +// GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32: rv32i/ilp32 +// GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32-NOT: {{^.+$}} + +// RUN: %clang %s \ +// RUN: -target riscv64-unknown-elf \ +// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \ +// RUN: --print-multi-directory \ +// RUN: -march=rv64imfc -mabi=lp64 \ +// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV64IMFC-LP64 %s +// GCC-MULTI-LIB-REUSE-RV64IMFC-LP64: . +// GCC-MULTI-LIB-REUSE-RV64IMFC-LP64-NOT: {{^.+$}} diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c index eacd5c4698842e6cd74ffa65aee88121f2019ba9..2831c2dad8d24cce4479b186f11a2e576ade483d 100644 --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -23,6 +23,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-NO-LINK-RUNTIME-LINUX %s // +// CHECK-ASAN-NO-LINK-RUNTIME-LINUX-NOT: libclang_rt.asan_static-x86_64 // CHECK-ASAN-NO-LINK-RUNTIME-LINUX-NOT: libclang_rt.asan-x86_64 // RUN: %clang -fsanitize=address -fno-sanitize-link-runtime -### %s 2>&1 \ @@ -31,6 +32,7 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-NO-LINK-RUNTIME-DARWIN %s // +// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN-NOT: libclang_rt.asan_static // CHECK-ASAN-NO-LINK-RUNTIME-DARWIN-NOT: libclang_rt.asan // RUN: %clang -fsanitize=address -### %s 2>&1 \ diff --git a/clang/test/Format/clang-format-ignore.cpp b/clang/test/Format/clang-format-ignore.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d6396a64a668de91d06aa91f2c93a64a701079d --- /dev/null +++ b/clang/test/Format/clang-format-ignore.cpp @@ -0,0 +1,33 @@ +// RUN: rm -rf %t.dir +// RUN: mkdir -p %t.dir/level1/level2 + +// RUN: cd %t.dir +// RUN: echo "*" > .clang-format-ignore +// RUN: echo "level*/*.c*" >> .clang-format-ignore +// RUN: echo "*/*2/foo.*" >> .clang-format-ignore +// RUN: touch foo.cc +// RUN: clang-format -verbose .clang-format-ignore foo.cc 2> %t.stderr +// RUN: not grep Formatting %t.stderr + +// RUN: cd level1 +// RUN: touch bar.cc baz.c +// RUN: clang-format -verbose bar.cc baz.c 2> %t.stderr +// RUN: not grep Formatting %t.stderr + +// RUN: cd level2 +// RUN: touch foo.c foo.js +// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr +// RUN: not grep Formatting %t.stderr + +// RUN: touch .clang-format-ignore +// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr +// RUN: grep "Formatting \[1/2] foo.c" %t.stderr +// RUN: grep "Formatting \[2/2] foo.js" %t.stderr + +// RUN: echo "*.js" > .clang-format-ignore +// RUN: clang-format -verbose foo.c foo.js 2> %t.stderr +// RUN: grep "Formatting \[1/2] foo.c" %t.stderr +// RUN: not grep "Formatting \[2/2] foo.js" %t.stderr + +// RUN: cd ../../.. +// RUN: rm -rf %t.dir diff --git a/clang/test/Headers/wasm.c b/clang/test/Headers/wasm.c index 9643cafc1ce6c31e13c54999f311c9a3bbe3040d..57f8b6d0db176a29ac71454b1f0c3e1c41aaf3b1 100644 --- a/clang/test/Headers/wasm.c +++ b/clang/test/Headers/wasm.c @@ -19,7 +19,7 @@ v128_t test_v128_load(const void *mem) { // CHECK-LABEL: @test_v128_load8_splat( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[MEM:%.*]], align 1, !tbaa [[TBAA2]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 [[TMP0]], i64 0 // CHECK-NEXT: [[VECINIT16_I:%.*]] = shufflevector <16 x i8> [[VECINIT_I]], <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[VECINIT16_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -31,7 +31,7 @@ v128_t test_v128_load8_splat(const void *mem) { // CHECK-LABEL: @test_v128_load16_splat( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[MEM:%.*]], align 1, !tbaa [[TBAA2]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[TMP0]], i64 0 // CHECK-NEXT: [[VECINIT8_I:%.*]] = shufflevector <8 x i16> [[VECINIT_I]], <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[VECINIT8_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -43,7 +43,7 @@ v128_t test_v128_load16_splat(const void *mem) { // CHECK-LABEL: @test_v128_load32_splat( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[MEM:%.*]], align 1, !tbaa [[TBAA2]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[TMP0]], i64 0 // CHECK-NEXT: [[VECINIT4_I:%.*]] = shufflevector <4 x i32> [[VECINIT_I]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: ret <4 x i32> [[VECINIT4_I]] // @@ -54,7 +54,7 @@ v128_t test_v128_load32_splat(const void *mem) { // CHECK-LABEL: @test_v128_load64_splat( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[MEM:%.*]], align 1, !tbaa [[TBAA2]] -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 [[TMP0]], i64 0 // CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <2 x i64> [[VECINIT_I]], <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[VECINIT2_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -248,7 +248,7 @@ void test_v128_store64_lane(uint64_t *ptr, v128_t vec) { // CHECK-LABEL: @test_i8x16_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 [[C3:%.*]], i64 3 @@ -273,7 +273,7 @@ v128_t test_i8x16_make(int8_t c0, int8_t c1, int8_t c2, int8_t c3, int8_t c4, in // CHECK-LABEL: @test_u8x16_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <16 x i8> [[VECINIT_I]], i8 [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <16 x i8> [[VECINIT1_I]], i8 [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <16 x i8> [[VECINIT2_I]], i8 [[C3:%.*]], i64 3 @@ -298,7 +298,7 @@ v128_t test_u8x16_make(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3, uint8_t c // CHECK-LABEL: @test_i16x8_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[C3:%.*]], i64 3 @@ -315,7 +315,7 @@ v128_t test_i16x8_make(int16_t c0, int16_t c1, int16_t c2, int16_t c3, int16_t c // CHECK-LABEL: @test_u16x8_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <8 x i16> [[VECINIT_I]], i16 [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <8 x i16> [[VECINIT1_I]], i16 [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <8 x i16> [[VECINIT2_I]], i16 [[C3:%.*]], i64 3 @@ -332,7 +332,7 @@ v128_t test_u16x8_make(uint16_t c0, uint16_t c1, uint16_t c2, uint16_t c3, uint1 // CHECK-LABEL: @test_i32x4_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[C3:%.*]], i64 3 @@ -344,7 +344,7 @@ v128_t test_i32x4_make(int32_t c0, int32_t c1, int32_t c2, int32_t c3) { // CHECK-LABEL: @test_u32x4_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x i32> [[VECINIT_I]], i32 [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x i32> [[VECINIT1_I]], i32 [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x i32> [[VECINIT2_I]], i32 [[C3:%.*]], i64 3 @@ -356,7 +356,7 @@ v128_t test_u32x4_make(uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3) { // CHECK-LABEL: @test_i64x2_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 [[C1:%.*]], i64 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[VECINIT1_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -367,7 +367,7 @@ v128_t test_i64x2_make(int64_t c0, int64_t c1) { // CHECK-LABEL: @test_u64x2_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x i64> [[VECINIT_I]], i64 [[C1:%.*]], i64 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[VECINIT1_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -378,7 +378,7 @@ v128_t test_u64x2_make(uint64_t c0, uint64_t c1) { // CHECK-LABEL: @test_f32x4_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float [[C1:%.*]], i64 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float [[C2:%.*]], i64 2 // CHECK-NEXT: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float [[C3:%.*]], i64 3 @@ -391,7 +391,7 @@ v128_t test_f32x4_make(float c0, float c1, float c2, float c3) { // CHECK-LABEL: @test_f64x2_make( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double [[C0:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[C0:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[C1:%.*]], i64 1 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[VECINIT1_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -562,7 +562,7 @@ v128_t test_f64x2_const_splat(void) { // CHECK-LABEL: @test_i8x16_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT15_I:%.*]] = shufflevector <16 x i8> [[VECINIT_I]], <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[VECINIT15_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -573,7 +573,7 @@ v128_t test_i8x16_splat(int8_t a) { // CHECK-LABEL: @test_u8x16_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <16 x i8> poison, i8 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT15_I:%.*]] = shufflevector <16 x i8> [[VECINIT_I]], <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[VECINIT15_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -626,7 +626,7 @@ v128_t test_u8x16_replace_lane(v128_t a, uint8_t b) { // CHECK-LABEL: @test_i16x8_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT7_I:%.*]] = shufflevector <8 x i16> [[VECINIT_I]], <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[VECINIT7_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -637,7 +637,7 @@ v128_t test_i16x8_splat(int16_t a) { // CHECK-LABEL: @test_u16x8_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> undef, i16 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x i16> poison, i16 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT7_I:%.*]] = shufflevector <8 x i16> [[VECINIT_I]], <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[VECINIT7_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -690,7 +690,7 @@ v128_t test_u16x8_replace_lane(v128_t a, uint16_t b) { // CHECK-LABEL: @test_i32x4_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT3_I:%.*]] = shufflevector <4 x i32> [[VECINIT_I]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: ret <4 x i32> [[VECINIT3_I]] // @@ -700,7 +700,7 @@ v128_t test_i32x4_splat(int32_t a) { // CHECK-LABEL: @test_u32x4_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x i32> poison, i32 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT3_I:%.*]] = shufflevector <4 x i32> [[VECINIT_I]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: ret <4 x i32> [[VECINIT3_I]] // @@ -746,7 +746,7 @@ v128_t test_u32x4_replace_lane(v128_t a, uint32_t b) { // CHECK-LABEL: @test_i64x2_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = shufflevector <2 x i64> [[VECINIT_I]], <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[VECINIT1_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -757,7 +757,7 @@ v128_t test_i64x2_splat(int64_t a) { // CHECK-LABEL: @test_u64x2_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x i64> poison, i64 [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = shufflevector <2 x i64> [[VECINIT_I]], <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[VECINIT1_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -810,7 +810,7 @@ v128_t test_u64x2_replace_lane(v128_t a, uint64_t b) { // CHECK-LABEL: @test_f32x4_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <4 x float> poison, float [[A:%.*]], i64 0 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[VECINIT_I]] to <4 x i32> // CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -842,7 +842,7 @@ v128_t test_f32x4_replace_lane(v128_t a, float b) { // CHECK-LABEL: @test_f64x2_splat( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> undef, double [[A:%.*]], i64 0 +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[A:%.*]], i64 0 // CHECK-NEXT: [[VECINIT1_I:%.*]] = shufflevector <2 x double> [[VECINIT_I]], <2 x double> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[VECINIT1_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -1572,7 +1572,7 @@ uint32_t test_i8x16_bitmask(v128_t a) { // CHECK-LABEL: @test_i8x16_popcnt( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> [[TMP0]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> [[TMP0]]), !range [[RNG5:![0-9]+]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP2]] // @@ -1585,7 +1585,7 @@ v128_t test_i8x16_popcnt(v128_t a) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 // CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// CHECK-NEXT: [[TMP3:%.*]] = insertelement <16 x i8> undef, i8 [[TMP2]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <16 x i8> poison, i8 [[TMP2]], i64 0 // CHECK-NEXT: [[SH_PROM_I:%.*]] = shufflevector <16 x i8> [[TMP3]], <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-NEXT: [[SHL_I:%.*]] = shl <16 x i8> [[TMP0]], [[SH_PROM_I]] // CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[SHL_I]] to <4 x i32> @@ -1600,7 +1600,7 @@ v128_t test_i8x16_shl(v128_t a, uint32_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 // CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// CHECK-NEXT: [[TMP3:%.*]] = insertelement <16 x i8> undef, i8 [[TMP2]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <16 x i8> poison, i8 [[TMP2]], i64 0 // CHECK-NEXT: [[SH_PROM_I:%.*]] = shufflevector <16 x i8> [[TMP3]], <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = ashr <16 x i8> [[TMP0]], [[SH_PROM_I]] // CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[SHR_I]] to <4 x i32> @@ -1615,7 +1615,7 @@ v128_t test_i8x16_shr(v128_t a, uint32_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8 // CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// CHECK-NEXT: [[TMP3:%.*]] = insertelement <16 x i8> undef, i8 [[TMP2]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <16 x i8> poison, i8 [[TMP2]], i64 0 // CHECK-NEXT: [[SH_PROM_I:%.*]] = shufflevector <16 x i8> [[TMP3]], <16 x i8> poison, <16 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = lshr <16 x i8> [[TMP0]], [[SH_PROM_I]] // CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[SHR_I]] to <4 x i32> @@ -1805,7 +1805,7 @@ uint32_t test_i16x8_bitmask(v128_t a) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i16 // CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> undef, i16 [[TMP2]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> poison, i16 [[TMP2]], i64 0 // CHECK-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i16> [[TMP3]], <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-NEXT: [[SHL_I:%.*]] = shl <8 x i16> [[TMP0]], [[SH_PROM_I]] // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[SHL_I]] to <4 x i32> @@ -1820,7 +1820,7 @@ v128_t test_i16x8_shl(v128_t a, uint32_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i16 // CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> undef, i16 [[TMP2]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> poison, i16 [[TMP2]], i64 0 // CHECK-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i16> [[TMP3]], <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = ashr <8 x i16> [[TMP0]], [[SH_PROM_I]] // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[SHR_I]] to <4 x i32> @@ -1835,7 +1835,7 @@ v128_t test_i16x8_shr(v128_t a, uint32_t b) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i16 // CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> undef, i16 [[TMP2]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> poison, i16 [[TMP2]], i64 0 // CHECK-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i16> [[TMP3]], <8 x i16> poison, <8 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = lshr <8 x i16> [[TMP0]], [[SH_PROM_I]] // CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i16> [[SHR_I]] to <4 x i32> @@ -2028,8 +2028,8 @@ uint32_t test_i32x4_bitmask(v128_t a) { // CHECK-LABEL: @test_i32x4_shl( // CHECK-NEXT: entry: -// CHECK-NEXT: [[REM_I:%.*]] = and i32 [[B:%.*]], 31 -// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <4 x i32> poison, i32 [[REM_I]], i64 0 +// CHECK-NEXT: [[AND_I:%.*]] = and i32 [[B:%.*]], 31 +// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <4 x i32> poison, i32 [[AND_I]], i64 0 // CHECK-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT_I]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: [[SHL_I:%.*]] = shl <4 x i32> [[A:%.*]], [[SPLAT_SPLAT_I]] // CHECK-NEXT: ret <4 x i32> [[SHL_I]] @@ -2040,8 +2040,8 @@ v128_t test_i32x4_shl(v128_t a, uint32_t b) { // CHECK-LABEL: @test_i32x4_shr( // CHECK-NEXT: entry: -// CHECK-NEXT: [[REM_I:%.*]] = and i32 [[B:%.*]], 31 -// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <4 x i32> poison, i32 [[REM_I]], i64 0 +// CHECK-NEXT: [[AND_I:%.*]] = and i32 [[B:%.*]], 31 +// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <4 x i32> poison, i32 [[AND_I]], i64 0 // CHECK-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT_I]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = ashr <4 x i32> [[A:%.*]], [[SPLAT_SPLAT_I]] // CHECK-NEXT: ret <4 x i32> [[SHR_I]] @@ -2052,8 +2052,8 @@ v128_t test_i32x4_shr(v128_t a, uint32_t b) { // CHECK-LABEL: @test_u32x4_shr( // CHECK-NEXT: entry: -// CHECK-NEXT: [[REM_I:%.*]] = and i32 [[B:%.*]], 31 -// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <4 x i32> poison, i32 [[REM_I]], i64 0 +// CHECK-NEXT: [[AND_I:%.*]] = and i32 [[B:%.*]], 31 +// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <4 x i32> poison, i32 [[AND_I]], i64 0 // CHECK-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <4 x i32> [[SPLAT_SPLATINSERT_I]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = lshr <4 x i32> [[A:%.*]], [[SPLAT_SPLAT_I]] // CHECK-NEXT: ret <4 x i32> [[SHR_I]] @@ -2183,8 +2183,8 @@ uint32_t test_i64x2_bitmask(v128_t a) { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64> // CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], 63 -// CHECK-NEXT: [[REM_I:%.*]] = zext nneg i32 [[TMP1]] to i64 -// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i64> poison, i64 [[REM_I]], i64 0 +// CHECK-NEXT: [[AND_I:%.*]] = zext nneg i32 [[TMP1]] to i64 +// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i64> poison, i64 [[AND_I]], i64 0 // CHECK-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i64> [[SPLAT_SPLATINSERT_I]], <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[SHL_I:%.*]] = shl <2 x i64> [[TMP0]], [[SPLAT_SPLAT_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SHL_I]] to <4 x i32> @@ -2198,8 +2198,8 @@ v128_t test_i64x2_shl(v128_t a, uint32_t b) { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64> // CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], 63 -// CHECK-NEXT: [[REM_I:%.*]] = zext nneg i32 [[TMP1]] to i64 -// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i64> poison, i64 [[REM_I]], i64 0 +// CHECK-NEXT: [[AND_I:%.*]] = zext nneg i32 [[TMP1]] to i64 +// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i64> poison, i64 [[AND_I]], i64 0 // CHECK-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i64> [[SPLAT_SPLATINSERT_I]], <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = ashr <2 x i64> [[TMP0]], [[SPLAT_SPLAT_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SHR_I]] to <4 x i32> @@ -2213,8 +2213,8 @@ v128_t test_i64x2_shr(v128_t a, uint32_t b) { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64> // CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], 63 -// CHECK-NEXT: [[REM_I:%.*]] = zext nneg i32 [[TMP1]] to i64 -// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i64> poison, i64 [[REM_I]], i64 0 +// CHECK-NEXT: [[AND_I:%.*]] = zext nneg i32 [[TMP1]] to i64 +// CHECK-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i64> poison, i64 [[AND_I]], i64 0 // CHECK-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i64> [[SPLAT_SPLATINSERT_I]], <2 x i64> poison, <2 x i32> zeroinitializer // CHECK-NEXT: [[SHR_I:%.*]] = lshr <2 x i64> [[TMP0]], [[SPLAT_SPLAT_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SHR_I]] to <4 x i32> @@ -2648,7 +2648,7 @@ v128_t test_f32x4_convert_u32x4(v128_t a) { // CHECK-LABEL: @test_f64x2_convert_low_i32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sitofp <2 x i32> [[VECINIT2_I]] to <2 x double> // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -2659,7 +2659,7 @@ v128_t test_f64x2_convert_low_i32x4(v128_t a) { // CHECK-LABEL: @test_f64x2_convert_low_u32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = uitofp <2 x i32> [[VECINIT2_I]] to <2 x double> // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -2705,7 +2705,7 @@ v128_t test_f32x4_demote_f64x2_zero(v128_t a) { // CHECK-LABEL: @test_f64x2_promote_low_f32x4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <4 x float> -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x float> [[TMP0]], <4 x float> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x float> [[TMP0]], <4 x float> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = fpext <2 x float> [[VECINIT2_I]] to <2 x double> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -2821,7 +2821,7 @@ v128_t test_u16x8_narrow_i32x4(v128_t a, v128_t b) { // CHECK-LABEL: @test_i16x8_extend_low_i8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sext <8 x i8> [[VECINIT14_I]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -2833,7 +2833,7 @@ v128_t test_i16x8_extend_low_i8x16(v128_t a) { // CHECK-LABEL: @test_i16x8_extend_high_i8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sext <8 x i8> [[VECINIT14_I]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -2845,7 +2845,7 @@ v128_t test_i16x8_extend_high_i8x16(v128_t a) { // CHECK-LABEL: @test_u16x8_extend_low_u8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = zext <8 x i8> [[VECINIT14_I]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -2857,7 +2857,7 @@ v128_t test_u16x8_extend_low_u8x16(v128_t a) { // CHECK-LABEL: @test_u16x8_extend_high_u8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = zext <8 x i8> [[VECINIT14_I]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP1]] @@ -2869,7 +2869,7 @@ v128_t test_u16x8_extend_high_u8x16(v128_t a) { // CHECK-LABEL: @test_i32x4_extend_low_i16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sext <4 x i16> [[VECINIT6_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[CONV_I]] // @@ -2880,7 +2880,7 @@ v128_t test_i32x4_extend_low_i16x8(v128_t a) { // CHECK-LABEL: @test_i32x4_extend_high_i16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sext <4 x i16> [[VECINIT6_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[CONV_I]] // @@ -2891,7 +2891,7 @@ v128_t test_i32x4_extend_high_i16x8(v128_t a) { // CHECK-LABEL: @test_u32x4_extend_low_u16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = zext <4 x i16> [[VECINIT6_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[CONV_I]] // @@ -2902,7 +2902,7 @@ v128_t test_u32x4_extend_low_u16x8(v128_t a) { // CHECK-LABEL: @test_u32x4_extend_high_u16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = zext <4 x i16> [[VECINIT6_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[CONV_I]] // @@ -2912,7 +2912,7 @@ v128_t test_u32x4_extend_high_u16x8(v128_t a) { // CHECK-LABEL: @test_i64x2_extend_low_i32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sext <2 x i32> [[VECINIT2_I]] to <2 x i64> // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -2923,7 +2923,7 @@ v128_t test_i64x2_extend_low_i32x4(v128_t a) { // CHECK-LABEL: @test_i64x2_extend_high_i32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = sext <2 x i32> [[VECINIT2_I]] to <2 x i64> // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -2934,7 +2934,7 @@ v128_t test_i64x2_extend_high_i32x4(v128_t a) { // CHECK-LABEL: @test_u64x2_extend_low_u32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = zext <2 x i32> [[VECINIT2_I]] to <2 x i64> // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -2945,7 +2945,7 @@ v128_t test_u64x2_extend_low_u32x4(v128_t a) { // CHECK-LABEL: @test_u64x2_extend_high_u32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I:%.*]] = zext <2 x i32> [[VECINIT2_I]] to <2 x i64> // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[CONV_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] @@ -2999,12 +2999,12 @@ v128_t test_u32x4_extadd_pairwise_u16x8(v128_t a) { // CHECK-LABEL: @test_i16x8_extmul_low_i8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = sext <8 x i8> [[VECINIT14_I2_I]] to <8 x i16> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <8 x i16> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <8 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <8 x i16> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP2]] // @@ -3015,12 +3015,12 @@ v128_t test_i16x8_extmul_low_i8x16(v128_t a, v128_t b) { // CHECK-LABEL: @test_i16x8_extmul_high_i8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = sext <8 x i8> [[VECINIT14_I2_I]] to <8 x i16> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <8 x i16> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <8 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <8 x i16> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP2]] // @@ -3031,12 +3031,12 @@ v128_t test_i16x8_extmul_high_i8x16(v128_t a, v128_t b) { // CHECK-LABEL: @test_u16x8_extmul_low_u8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = zext <8 x i8> [[VECINIT14_I2_I]] to <8 x i16> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <8 x i16> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <8 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <8 x i16> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP2]] // @@ -3047,12 +3047,12 @@ v128_t test_u16x8_extmul_low_u8x16(v128_t a, v128_t b) { // CHECK-LABEL: @test_u16x8_extmul_high_u8x16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> undef, <8 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> -// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> undef, <8 x i32> +// CHECK-NEXT: [[VECINIT14_I2_I:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <8 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = zext <8 x i8> [[VECINIT14_I2_I]] to <8 x i16> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <8 x i16> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VECINIT14_I_I:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <8 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <8 x i8> [[VECINIT14_I_I]] to <8 x i16> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <8 x i16> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i16> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP2]] // @@ -3063,12 +3063,12 @@ v128_t test_u16x8_extmul_high_u8x16(v128_t a, v128_t b) { // CHECK-LABEL: @test_i32x4_extmul_low_i16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = sext <4 x i16> [[VECINIT6_I2_I]] to <4 x i32> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <4 x i32> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> +// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <4 x i32> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: ret <4 x i32> [[MUL_I]] // v128_t test_i32x4_extmul_low_i16x8(v128_t a, v128_t b) { @@ -3078,12 +3078,12 @@ v128_t test_i32x4_extmul_low_i16x8(v128_t a, v128_t b) { // CHECK-LABEL: @test_i32x4_extmul_high_i16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = sext <4 x i16> [[VECINIT6_I2_I]] to <4 x i32> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <4 x i32> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> +// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <4 x i32> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: ret <4 x i32> [[MUL_I]] // v128_t test_i32x4_extmul_high_i16x8(v128_t a, v128_t b) { @@ -3093,12 +3093,12 @@ v128_t test_i32x4_extmul_high_i16x8(v128_t a, v128_t b) { // CHECK-LABEL: @test_u32x4_extmul_low_u16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = zext <4 x i16> [[VECINIT6_I2_I]] to <4 x i32> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <4 x i32> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> +// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <4 x i32> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: ret <4 x i32> [[MUL_I]] // v128_t test_u32x4_extmul_low_u16x8(v128_t a, v128_t b) { @@ -3108,12 +3108,12 @@ v128_t test_u32x4_extmul_low_u16x8(v128_t a, v128_t b) { // CHECK-LABEL: @test_u32x4_extmul_high_u16x8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> undef, <4 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> -// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> -// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <4 x i32> +// CHECK-NEXT: [[VECINIT6_I2_I:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <4 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = zext <4 x i16> [[VECINIT6_I2_I]] to <4 x i32> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <4 x i32> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B:%.*]] to <8 x i16> +// CHECK-NEXT: [[VECINIT6_I_I:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <4 x i16> [[VECINIT6_I_I]] to <4 x i32> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <4 x i32> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: ret <4 x i32> [[MUL_I]] // v128_t test_u32x4_extmul_high_u16x8(v128_t a, v128_t b) { @@ -3122,11 +3122,11 @@ v128_t test_u32x4_extmul_high_u16x8(v128_t a, v128_t b) { // CHECK-LABEL: @test_i64x2_extmul_low_i32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> -// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = sext <2 x i32> [[VECINIT2_I2_I]] to <2 x i64> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <2 x i64> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <2 x i64> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] // @@ -3136,11 +3136,11 @@ v128_t test_i64x2_extmul_low_i32x4(v128_t a, v128_t b) { // CHECK-LABEL: @test_i64x2_extmul_high_i32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> -// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = sext <2 x i32> [[VECINIT2_I2_I]] to <2 x i64> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <2 x i64> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = sext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nsw <2 x i64> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] // @@ -3150,11 +3150,11 @@ v128_t test_i64x2_extmul_high_i32x4(v128_t a, v128_t b) { // CHECK-LABEL: @test_u64x2_extmul_low_u32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> -// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = zext <2 x i32> [[VECINIT2_I2_I]] to <2 x i64> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <2 x i64> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <2 x i64> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] // @@ -3164,11 +3164,11 @@ v128_t test_u64x2_extmul_low_u32x4(v128_t a, v128_t b) { // CHECK-LABEL: @test_u64x2_extmul_high_u32x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> undef, <2 x i32> -// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> -// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> undef, <2 x i32> +// CHECK-NEXT: [[VECINIT2_I2_I:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> // CHECK-NEXT: [[CONV_I3_I:%.*]] = zext <2 x i32> [[VECINIT2_I2_I]] to <2 x i64> -// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <2 x i64> [[CONV_I3_I]], [[CONV_I_I]] +// CHECK-NEXT: [[VECINIT2_I_I:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[CONV_I_I:%.*]] = zext <2 x i32> [[VECINIT2_I_I]] to <2 x i64> +// CHECK-NEXT: [[MUL_I:%.*]] = mul nuw <2 x i64> [[CONV_I_I]], [[CONV_I3_I]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[MUL_I]] to <4 x i32> // CHECK-NEXT: ret <4 x i32> [[TMP0]] // diff --git a/clang/test/Index/Inputs/Frameworks/module.map b/clang/test/Index/Inputs/Frameworks/module.modulemap similarity index 100% rename from clang/test/Index/Inputs/Frameworks/module.map rename to clang/test/Index/Inputs/Frameworks/module.modulemap diff --git a/clang/test/Index/Inputs/Headers/module.map b/clang/test/Index/Inputs/Headers/module.modulemap similarity index 100% rename from clang/test/Index/Inputs/Headers/module.map rename to clang/test/Index/Inputs/Headers/module.modulemap diff --git a/clang/test/Index/Inputs/Headers/nested/module.map b/clang/test/Index/Inputs/Headers/nested/module.modulemap similarity index 100% rename from clang/test/Index/Inputs/Headers/nested/module.map rename to clang/test/Index/Inputs/Headers/nested/module.modulemap diff --git a/clang/test/Index/Inputs/module.map b/clang/test/Index/Inputs/module.modulemap similarity index 100% rename from clang/test/Index/Inputs/module.map rename to clang/test/Index/Inputs/module.modulemap diff --git a/clang/test/Index/Inputs/vfsoverlay.yaml b/clang/test/Index/Inputs/vfsoverlay.yaml index 95b00bef7d0e4c45194ec451b4e5aefc32d27f93..3e9718b4c4314f617d3213db06f0b139eb90ac7f 100644 --- a/clang/test/Index/Inputs/vfsoverlay.yaml +++ b/clang/test/Index/Inputs/vfsoverlay.yaml @@ -3,8 +3,8 @@ 'roots': [ { 'name': 'OUT_DIR', 'type': 'directory', 'contents': [ - { 'name': 'module.map', 'type': 'file', - 'external-contents': 'INPUT_DIR/module.map' + { 'name': 'module.modulemap', 'type': 'file', + 'external-contents': 'INPUT_DIR/module.modulemap' }, { 'name': 'ModuleNeedsVFS.h', 'type': 'file', 'external-contents': 'INPUT_DIR/module_needs_vfs.h' diff --git a/clang/test/Lexer/case-insensitive-include-absolute.c b/clang/test/Lexer/case-insensitive-include-absolute.c new file mode 100644 index 0000000000000000000000000000000000000000..6247e4808c7fa23caf34ccb0d0f7fc5f708479ce --- /dev/null +++ b/clang/test/Lexer/case-insensitive-include-absolute.c @@ -0,0 +1,13 @@ +// REQUIRES: case-insensitive-filesystem + +// RUN: rm -rf %t && split-file %s %t +// RUN: sed "s|DIR|%/t|g" %t/tu.c.in > %t/tu.c +// RUN: %clang_cc1 -fsyntax-only %t/tu.c 2>&1 | FileCheck %s --DDIR=%/t + +//--- header.h +//--- tu.c.in +#import "DIR/Header.h" +// CHECK: tu.c:1:9: warning: non-portable path to file '"[[DIR]]/header.h"'; specified path differs in case from file name on disk [-Wnonportable-include-path] +// CHECK-NEXT: 1 | #import "[[DIR]]/Header.h" +// CHECK-NEXT: | ^~~~~~~~~~~~~~~~~~ +// CHECK-NEXT: | "[[DIR]]/header.h" diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index bdfda430eea86c5ae5f4ff5a193ce225a29dabdf..7b0cda0bca078d596e0db68254eb2b5f3093fa21 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -61,7 +61,6 @@ // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record) // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record) // CHECK-NEXT: CoroWrapper (SubjectMatchRule_function) -// CHECK-NEXT: CountedBy (SubjectMatchRule_field) // CHECK-NEXT: DLLExport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface) // CHECK-NEXT: DLLImport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface) // CHECK-NEXT: Destructor (SubjectMatchRule_function) diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c index e840a9208f5a4507f988618008bd1d1abd275709..48e9f05d9b03de2a3b9166d9e29bdb0967b4309d 100644 --- a/clang/test/Misc/target-invalid-cpu-note.c +++ b/clang/test/Misc/target-invalid-cpu-note.c @@ -85,7 +85,7 @@ // RUN: not %clang_cc1 -triple riscv64 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV64 // RISCV64: error: unknown target CPU 'not-a-cpu' -// RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, sifive-x280, veyron-v1, xiangshan-nanhu{{$}} +// RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-p450, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, sifive-x280, veyron-v1, xiangshan-nanhu{{$}} // RUN: not %clang_cc1 -triple riscv32 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV32 // TUNE-RISCV32: error: unknown target CPU 'not-a-cpu' @@ -93,4 +93,4 @@ // RUN: not %clang_cc1 -triple riscv64 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV64 // TUNE-RISCV64: error: unknown target CPU 'not-a-cpu' -// TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, sifive-x280, veyron-v1, xiangshan-nanhu, generic, rocket, sifive-7-series{{$}} +// TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-p450, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, sifive-x280, veyron-v1, xiangshan-nanhu, generic, rocket, sifive-7-series{{$}} diff --git a/clang/test/Modules/Inputs/Conflicts/module.map b/clang/test/Modules/Inputs/Conflicts/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/Conflicts/module.map rename to clang/test/Modules/Inputs/Conflicts/module.modulemap diff --git a/clang/test/Modules/Inputs/DependsOnModule.framework/module.map b/clang/test/Modules/Inputs/DependsOnModule.framework/Modules/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/DependsOnModule.framework/module.map rename to clang/test/Modules/Inputs/DependsOnModule.framework/Modules/module.modulemap diff --git a/clang/test/Modules/Inputs/DependsOnModule.framework/module_private.map b/clang/test/Modules/Inputs/DependsOnModule.framework/Modules/module.private.modulemap similarity index 100% rename from clang/test/Modules/Inputs/DependsOnModule.framework/module_private.map rename to clang/test/Modules/Inputs/DependsOnModule.framework/Modules/module.private.modulemap diff --git a/clang/test/Modules/Inputs/GNUAsm/NeedsGNUInlineAsm.framework/module.map b/clang/test/Modules/Inputs/GNUAsm/NeedsGNUInlineAsm.framework/Modules/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/GNUAsm/NeedsGNUInlineAsm.framework/module.map rename to clang/test/Modules/Inputs/GNUAsm/NeedsGNUInlineAsm.framework/Modules/module.modulemap diff --git a/clang/test/Modules/Inputs/Modified/module.map b/clang/test/Modules/Inputs/Modified/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/Modified/module.map rename to clang/test/Modules/Inputs/Modified/module.modulemap diff --git a/clang/test/Modules/Inputs/ModuleDiags/module.map b/clang/test/Modules/Inputs/ModuleDiags/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/ModuleDiags/module.map rename to clang/test/Modules/Inputs/ModuleDiags/module.modulemap diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/a.h b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/a.h new file mode 100644 index 0000000000000000000000000000000000000000..d571c6e4f799f3f2aaa4c0ac3a409c4d70490413 --- /dev/null +++ b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/a.h @@ -0,0 +1 @@ +void will_be_found1(void); diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/module.map b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/module.map new file mode 100644 index 0000000000000000000000000000000000000000..ef46443cedc925aff36b70023f5f50156a9421c0 --- /dev/null +++ b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/module.map @@ -0,0 +1,3 @@ +module module_map { + header "a.h" +} diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/module_private.map b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/module_private.map new file mode 100644 index 0000000000000000000000000000000000000000..d542172a1235e74f33ca9482523bc6bf128b1dda --- /dev/null +++ b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/module_private.map @@ -0,0 +1,3 @@ +module module_map.Private { + header "private.h" +} diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/private.h b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map/private.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/Headers/a.h b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/Headers/a.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/PrivateHeaders/private.h b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/PrivateHeaders/private.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/module.map b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/module.map new file mode 100644 index 0000000000000000000000000000000000000000..f30545f8a88cdd5fa89ec11a262c3defce074e7c --- /dev/null +++ b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/module.map @@ -0,0 +1,3 @@ +framework module Module_Map_F { + header "a.h" +} diff --git a/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/module_private.map b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/module_private.map new file mode 100644 index 0000000000000000000000000000000000000000..0b3b5a78b8741d1f4099d0532a0acce420548a7f --- /dev/null +++ b/clang/test/Modules/Inputs/ModuleMapLocations/Module_Map_F.framework/module_private.map @@ -0,0 +1,3 @@ +explicit framework module Module_Map_F.Private { + header "private.h" +} diff --git a/clang/test/Modules/Inputs/NoUmbrella.framework/module.map b/clang/test/Modules/Inputs/NoUmbrella.framework/Modules/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/NoUmbrella.framework/module.map rename to clang/test/Modules/Inputs/NoUmbrella.framework/Modules/module.modulemap diff --git a/clang/test/Modules/Inputs/NoUmbrella.framework/module_private.map b/clang/test/Modules/Inputs/NoUmbrella.framework/Modules/module.private.modulemap similarity index 100% rename from clang/test/Modules/Inputs/NoUmbrella.framework/module_private.map rename to clang/test/Modules/Inputs/NoUmbrella.framework/Modules/module.private.modulemap diff --git a/clang/test/Modules/Inputs/StdDef/module.map b/clang/test/Modules/Inputs/StdDef/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/StdDef/module.map rename to clang/test/Modules/Inputs/StdDef/module.modulemap diff --git a/clang/test/Modules/Inputs/System/usr/include/module.map b/clang/test/Modules/Inputs/System/usr/include/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/System/usr/include/module.map rename to clang/test/Modules/Inputs/System/usr/include/module.modulemap diff --git a/clang/test/Modules/Inputs/UseAfterFree/module.map b/clang/test/Modules/Inputs/UseAfterFree/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/UseAfterFree/module.map rename to clang/test/Modules/Inputs/UseAfterFree/module.modulemap diff --git a/clang/test/Modules/Inputs/UseAfterFree/module_private.map b/clang/test/Modules/Inputs/UseAfterFree/module.private.modulemap similarity index 100% rename from clang/test/Modules/Inputs/UseAfterFree/module_private.map rename to clang/test/Modules/Inputs/UseAfterFree/module.private.modulemap diff --git a/clang/test/Modules/Inputs/crash-recovery/usr/include/module.map b/clang/test/Modules/Inputs/crash-recovery/usr/include/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/crash-recovery/usr/include/module.map rename to clang/test/Modules/Inputs/crash-recovery/usr/include/module.modulemap diff --git a/clang/test/Modules/Inputs/declare-use/module.map b/clang/test/Modules/Inputs/declare-use/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/declare-use/module.map rename to clang/test/Modules/Inputs/declare-use/module.modulemap diff --git a/clang/test/Modules/Inputs/elsewhere/module.map b/clang/test/Modules/Inputs/elsewhere/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/elsewhere/module.map rename to clang/test/Modules/Inputs/elsewhere/module.modulemap diff --git a/clang/test/Modules/Inputs/exclude-header/module.map b/clang/test/Modules/Inputs/exclude-header/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/exclude-header/module.map rename to clang/test/Modules/Inputs/exclude-header/module.modulemap diff --git a/clang/test/Modules/Inputs/implicit-private-without-public/DeprecatedModuleMapLocation.framework/module_private.map b/clang/test/Modules/Inputs/implicit-private-without-public/DeprecatedModuleMapLocation.framework/module.private.modulemap similarity index 100% rename from clang/test/Modules/Inputs/implicit-private-without-public/DeprecatedModuleMapLocation.framework/module_private.map rename to clang/test/Modules/Inputs/implicit-private-without-public/DeprecatedModuleMapLocation.framework/module.private.modulemap diff --git a/clang/test/Modules/Inputs/include-relative/module.map b/clang/test/Modules/Inputs/include-relative/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/include-relative/module.map rename to clang/test/Modules/Inputs/include-relative/module.modulemap diff --git a/clang/test/Modules/Inputs/lookup-assert-protocol/module.map b/clang/test/Modules/Inputs/lookup-assert-protocol/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/lookup-assert-protocol/module.map rename to clang/test/Modules/Inputs/lookup-assert-protocol/module.modulemap diff --git a/clang/test/Modules/Inputs/lookup-assert/module.map b/clang/test/Modules/Inputs/lookup-assert/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/lookup-assert/module.map rename to clang/test/Modules/Inputs/lookup-assert/module.modulemap diff --git a/clang/test/Modules/Inputs/macro-undef-through-pch/module.map b/clang/test/Modules/Inputs/macro-undef-through-pch/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/macro-undef-through-pch/module.map rename to clang/test/Modules/Inputs/macro-undef-through-pch/module.modulemap diff --git a/clang/test/Modules/Inputs/malformed/module.map b/clang/test/Modules/Inputs/malformed/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/malformed/module.map rename to clang/test/Modules/Inputs/malformed/module.modulemap diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/module.map rename to clang/test/Modules/Inputs/module.modulemap diff --git a/clang/test/Modules/Inputs/ms-enums/module.map b/clang/test/Modules/Inputs/ms-enums/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/ms-enums/module.map rename to clang/test/Modules/Inputs/ms-enums/module.modulemap diff --git a/clang/test/Modules/Inputs/normal-module-map/Umbrella/module.map b/clang/test/Modules/Inputs/normal-module-map/Umbrella/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/normal-module-map/Umbrella/module.map rename to clang/test/Modules/Inputs/normal-module-map/Umbrella/module.modulemap diff --git a/clang/test/Modules/Inputs/normal-module-map/Umbrella2/module.map b/clang/test/Modules/Inputs/normal-module-map/Umbrella2/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/normal-module-map/Umbrella2/module.map rename to clang/test/Modules/Inputs/normal-module-map/Umbrella2/module.modulemap diff --git a/clang/test/Modules/Inputs/normal-module-map/module.map b/clang/test/Modules/Inputs/normal-module-map/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/normal-module-map/module.map rename to clang/test/Modules/Inputs/normal-module-map/module.modulemap diff --git a/clang/test/Modules/Inputs/normal-module-map/nested/module.map b/clang/test/Modules/Inputs/normal-module-map/nested/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/normal-module-map/nested/module.map rename to clang/test/Modules/Inputs/normal-module-map/nested/module.modulemap diff --git a/clang/test/Modules/Inputs/objc-category-2/module.map b/clang/test/Modules/Inputs/objc-category-2/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/objc-category-2/module.map rename to clang/test/Modules/Inputs/objc-category-2/module.modulemap diff --git a/clang/test/Modules/Inputs/objc-category-3/module.map b/clang/test/Modules/Inputs/objc-category-3/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/objc-category-3/module.map rename to clang/test/Modules/Inputs/objc-category-3/module.modulemap diff --git a/clang/test/Modules/Inputs/objc-category/module.map b/clang/test/Modules/Inputs/objc-category/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/objc-category/module.map rename to clang/test/Modules/Inputs/objc-category/module.modulemap diff --git a/clang/test/Modules/Inputs/objc-hidden/System/module.map b/clang/test/Modules/Inputs/objc-hidden/System/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/objc-hidden/System/module.map rename to clang/test/Modules/Inputs/objc-hidden/System/module.modulemap diff --git a/clang/test/Modules/Inputs/odr/module.map b/clang/test/Modules/Inputs/odr/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/odr/module.map rename to clang/test/Modules/Inputs/odr/module.modulemap diff --git a/clang/test/Modules/Inputs/oldname/module.map b/clang/test/Modules/Inputs/oldname/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/oldname/module.map rename to clang/test/Modules/Inputs/oldname/module.modulemap diff --git a/clang/test/Modules/Inputs/pr19692/module.map b/clang/test/Modules/Inputs/pr19692/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/pr19692/module.map rename to clang/test/Modules/Inputs/pr19692/module.modulemap diff --git a/clang/test/Modules/Inputs/private/module.map b/clang/test/Modules/Inputs/private/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/private/module.map rename to clang/test/Modules/Inputs/private/module.modulemap diff --git a/clang/test/Modules/Inputs/private1/module.map b/clang/test/Modules/Inputs/private1/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/private1/module.map rename to clang/test/Modules/Inputs/private1/module.modulemap diff --git a/clang/test/Modules/Inputs/private2/module.map b/clang/test/Modules/Inputs/private2/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/private2/module.map rename to clang/test/Modules/Inputs/private2/module.modulemap diff --git a/clang/test/Modules/Inputs/redecls/module.map b/clang/test/Modules/Inputs/redecls/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/redecls/module.map rename to clang/test/Modules/Inputs/redecls/module.modulemap diff --git a/clang/test/Modules/Inputs/self-import-header/af.framework/module.map b/clang/test/Modules/Inputs/self-import-header/af.framework/Modules/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/self-import-header/af.framework/module.map rename to clang/test/Modules/Inputs/self-import-header/af.framework/Modules/module.modulemap diff --git a/clang/test/Modules/Inputs/self-import-header/depend_builtin/module.map b/clang/test/Modules/Inputs/self-import-header/depend_builtin/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/self-import-header/depend_builtin/module.map rename to clang/test/Modules/Inputs/self-import-header/depend_builtin/module.modulemap diff --git a/clang/test/Modules/Inputs/string_names/module.map b/clang/test/Modules/Inputs/string_names/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/string_names/module.map rename to clang/test/Modules/Inputs/string_names/module.modulemap diff --git a/clang/test/Modules/Inputs/subdir/module.map b/clang/test/Modules/Inputs/subdir/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/subdir/module.map rename to clang/test/Modules/Inputs/subdir/module.modulemap diff --git a/clang/test/Modules/Inputs/subdirectory-module-maps-working-dir/subdir_module/module.map b/clang/test/Modules/Inputs/subdirectory-module-maps-working-dir/subdir_module/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/subdirectory-module-maps-working-dir/subdir_module/module.map rename to clang/test/Modules/Inputs/subdirectory-module-maps-working-dir/subdir_module/module.modulemap diff --git a/clang/test/Modules/Inputs/submodules/module.map b/clang/test/Modules/Inputs/submodules/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/submodules/module.map rename to clang/test/Modules/Inputs/submodules/module.modulemap diff --git a/clang/test/Modules/Inputs/system-out-of-date/module.map b/clang/test/Modules/Inputs/system-out-of-date/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/system-out-of-date/module.map rename to clang/test/Modules/Inputs/system-out-of-date/module.modulemap diff --git a/clang/test/Modules/Inputs/template-specialization-visibility/module.map b/clang/test/Modules/Inputs/template-specialization-visibility/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/template-specialization-visibility/module.map rename to clang/test/Modules/Inputs/template-specialization-visibility/module.modulemap diff --git a/clang/test/Modules/Inputs/thread-safety/module.map b/clang/test/Modules/Inputs/thread-safety/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/thread-safety/module.map rename to clang/test/Modules/Inputs/thread-safety/module.modulemap diff --git a/clang/test/Modules/Inputs/undefined-type-fixit/module.map b/clang/test/Modules/Inputs/undefined-type-fixit/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/undefined-type-fixit/module.map rename to clang/test/Modules/Inputs/undefined-type-fixit/module.modulemap diff --git a/clang/test/Modules/Inputs/unnecessary-module-map-parsing/module.map b/clang/test/Modules/Inputs/unnecessary-module-map-parsing/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/unnecessary-module-map-parsing/module.map rename to clang/test/Modules/Inputs/unnecessary-module-map-parsing/module.modulemap diff --git a/clang/test/Modules/Inputs/update-after-load/module.map b/clang/test/Modules/Inputs/update-after-load/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/update-after-load/module.map rename to clang/test/Modules/Inputs/update-after-load/module.modulemap diff --git a/clang/test/Modules/Inputs/wildcard-submodule-exports/module.map b/clang/test/Modules/Inputs/wildcard-submodule-exports/module.modulemap similarity index 100% rename from clang/test/Modules/Inputs/wildcard-submodule-exports/module.map rename to clang/test/Modules/Inputs/wildcard-submodule-exports/module.modulemap diff --git a/clang/test/Modules/concept_differ.cpp b/clang/test/Modules/concept_differ.cpp index 23c7d4c5ecf9ab4ef2c5caed25252013dcd0b6ad..9c1d292f29274b425e5caf974312c6c6a9eda028 100644 --- a/clang/test/Modules/concept_differ.cpp +++ b/clang/test/Modules/concept_differ.cpp @@ -2,9 +2,9 @@ // RUN: mkdir %t // RUN: split-file %s %t // -// RUN: %clang_cc1 -x c++ -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.map %t/foo.cpp -verify +// RUN: %clang_cc1 -x c++ -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.modulemap %t/foo.cpp -verify -//--- module.map +//--- module.modulemap module "foo" { export * header "foo.h" diff --git a/clang/test/Modules/config_macros.m b/clang/test/Modules/config_macros.m index dd071993809beb5ce414c9fa926ba960119dcd77..15e2c16606ba29db7887ead7f44c62e26193a7d3 100644 --- a/clang/test/Modules/config_macros.m +++ b/clang/test/Modules/config_macros.m @@ -23,6 +23,6 @@ char *test_bar(void) { @import config; // expected-warning{{definition of configuration macro 'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on the command line to configure the module}} // RUN: rm -rf %t -// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.map +// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.modulemap // RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify diff --git a/clang/test/Modules/crash-vfs-ivfsoverlay.m b/clang/test/Modules/crash-vfs-ivfsoverlay.m index d2d2ccbd2546bc9ae19dbce59dfa7c5cb11f4891..32489457d7362819ddd4b29f0f72a08088db5209 100644 --- a/clang/test/Modules/crash-vfs-ivfsoverlay.m +++ b/clang/test/Modules/crash-vfs-ivfsoverlay.m @@ -41,5 +41,5 @@ // CHECKYAML: 'contents': [ // CHECKYAML-NEXT: { // CHECKYAML-NEXT: 'type': 'file', -// CHECKYAML-NEXT: 'name': "module.map", +// CHECKYAML-NEXT: 'name': "module.modulemap", // CHECKYAML-NEXT: 'external-contents': "/[[OTHERPATH:.*]]/actual_module2.map" diff --git a/clang/test/Modules/crash-vfs-path-symlink-component.m b/clang/test/Modules/crash-vfs-path-symlink-component.m index 8280cd79bbc21ce7180ef16c511873c6853fcd9a..fe6e4d6ff42457067e79cb6a8b3aac818c9c51ae 100644 --- a/clang/test/Modules/crash-vfs-path-symlink-component.m +++ b/clang/test/Modules/crash-vfs-path-symlink-component.m @@ -49,8 +49,8 @@ // CHECKYAML-NEXT: 'contents': [ // CHECKYAML-NEXT: { // CHECKYAML-NEXT: 'type': 'file', -// CHECKYAML-NEXT: 'name': "module.map", -// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/i/usr/include/module.map" +// CHECKYAML-NEXT: 'name': "module.modulemap", +// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/i/usr/include/module.modulemap" // CHECKYAML-NEXT: }, // Test that by using the previous generated YAML file clang is able to find the diff --git a/clang/test/Modules/crash-vfs-path-traversal.m b/clang/test/Modules/crash-vfs-path-traversal.m index 891c7960f08b1f9251cc3a39e87dc60d1df50a46..d6c9a0f2aeb8a2f64aafaed2b81bbea15d917d85 100644 --- a/clang/test/Modules/crash-vfs-path-traversal.m +++ b/clang/test/Modules/crash-vfs-path-traversal.m @@ -46,8 +46,8 @@ // CHECKYAML-NEXT: 'contents': [ // CHECKYAML-NEXT: { // CHECKYAML-NEXT: 'type': 'file', -// CHECKYAML-NEXT: 'name': "module.map", -// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map" +// CHECKYAML-NEXT: 'name': "module.modulemap", +// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.modulemap" // CHECKYAML-NEXT: }, // Replace the paths in the YAML files with relative ".." traversals diff --git a/clang/test/Modules/crash-vfs-relative-incdir.m b/clang/test/Modules/crash-vfs-relative-incdir.m index e35c1e9fdb6591f8958e6ee60c0a99be1cdbea9a..c0407f776778b17bc3eb53d165b6e34c715e3da6 100644 --- a/clang/test/Modules/crash-vfs-relative-incdir.m +++ b/clang/test/Modules/crash-vfs-relative-incdir.m @@ -41,9 +41,9 @@ // CHECKYAML-NEXT: 'contents': [ // CHECKYAML-NEXT: { // CHECKYAML-NEXT: 'type': 'file', -// CHECKYAML-NEXT: 'name': "module.map", +// CHECKYAML-NEXT: 'name': "module.modulemap", // CHECKYAML-NOT: 'external-contents': "{{[^ ]*}}.cache -// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map" +// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.modulemap" // CHECKYAML-NEXT: }, // Run the reproducer script - regular exit code is enough to test it works. diff --git a/clang/test/Modules/crash-vfs-relative-overlay.m b/clang/test/Modules/crash-vfs-relative-overlay.m index ce2902417943c92d4f75dd010a8e003e6bc6552e..27f9c8d8906665fe2863725b32bfd8756cf6e6e2 100644 --- a/clang/test/Modules/crash-vfs-relative-overlay.m +++ b/clang/test/Modules/crash-vfs-relative-overlay.m @@ -44,9 +44,9 @@ // CHECKYAML-NEXT: 'contents': [ // CHECKYAML-NEXT: { // CHECKYAML-NEXT: 'type': 'file', -// CHECKYAML-NEXT: 'name': "module.map", +// CHECKYAML-NEXT: 'name': "module.modulemap", // CHECKYAML-NOT: 'external-contents': "{{[^ ]*}}.cache -// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map" +// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.modulemap" // CHECKYAML-NEXT: }, // Test that reading the YAML file will yield the correct path after diff --git a/clang/test/Modules/crash-vfs-run-reproducer.m b/clang/test/Modules/crash-vfs-run-reproducer.m index d43f7b5e4475da32ce9b62e63ea00b53d98aaedc..fd861fed5a60388e610df92605c813ac34738ad9 100644 --- a/clang/test/Modules/crash-vfs-run-reproducer.m +++ b/clang/test/Modules/crash-vfs-run-reproducer.m @@ -41,9 +41,9 @@ // CHECKYAML-NEXT: 'contents': [ // CHECKYAML-NEXT: { // CHECKYAML-NEXT: 'type': 'file', -// CHECKYAML-NEXT: 'name': "module.map", +// CHECKYAML-NEXT: 'name': "module.modulemap", // CHECKYAML-NOT: 'external-contents': "{{[^ ]*}}.cache -// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.map" +// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/Inputs/crash-recovery/usr/include/module.modulemap" // CHECKYAML-NEXT: }, // Run the reproducer script - regular exit code is enough to test it works. diff --git a/clang/test/Modules/declare-use-compatible.cpp b/clang/test/Modules/declare-use-compatible.cpp index a2e7f01c6c1d19712d97d47acb4b19e720ea9ef1..75ef5b00508d4cb48a6322d2a2954eec4c2c0ef7 100644 --- a/clang/test/Modules/declare-use-compatible.cpp +++ b/clang/test/Modules/declare-use-compatible.cpp @@ -1,7 +1,7 @@ // Used module not built with -decluse. // RUN: rm -rf %t // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodule-name=XB -emit-module \ -// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.map -o %t/b.pcm +// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.modulemap -o %t/b.pcm // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \ // RUN: -fmodules-decluse \ // RUN: -fmodule-file=%t/b.pcm -fmodule-name=XE -I %S/Inputs/declare-use %s @@ -10,14 +10,14 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodule-name=XB -emit-module \ // RUN: -fmodules-decluse \ -// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.map -o %t/b.pcm +// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.modulemap -o %t/b.pcm // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \ // RUN: -fmodule-file=%t/b.pcm -fmodule-name=XE -I %S/Inputs/declare-use %s // // Used module not built with -decluse. // RUN: rm -rf %t // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodule-name=XB -emit-module \ -// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.map -o %t/b.pcm +// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.modulemap -o %t/b.pcm // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \ // RUN: -fmodules-strict-decluse \ // RUN: -fmodule-file=%t/b.pcm -fmodule-name=XE -I %S/Inputs/declare-use %s @@ -26,7 +26,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodule-name=XB -emit-module \ // RUN: -fmodules-strict-decluse \ -// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.map -o %t/b.pcm +// RUN: -I %S/Inputs/declare-use %S/Inputs/declare-use/module.modulemap -o %t/b.pcm // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \ // RUN: -fmodule-file=%t/b.pcm -fmodule-name=XE -I %S/Inputs/declare-use %s diff --git a/clang/test/Modules/dependency-gen-pch.m b/clang/test/Modules/dependency-gen-pch.m index 589865e71d68aedb97ef28e5fdd2b38c2ab680ee..bdc226ffe33c8a12809bfd0697713cce47d2956c 100644 --- a/clang/test/Modules/dependency-gen-pch.m +++ b/clang/test/Modules/dependency-gen-pch.m @@ -6,7 +6,7 @@ // RUN: FileCheck %s < %t.d // CHECK: dependency-gen-pch.m.o // CHECK-NEXT: dependency-gen-pch.m -// CHECK-NEXT: Inputs{{.}}module.map +// CHECK-NEXT: Inputs{{.}}module.modulemap // CHECK-NEXT: diamond_top.pcm // CHECK-NEXT: Inputs{{.}}diamond_top.h diff --git a/clang/test/Modules/dependency-gen.m b/clang/test/Modules/dependency-gen.m index cb0a87595605216b017816fb80844109c91703e4..cdf170238d6f6779a7eb3027c6fbd748cf10fe70 100644 --- a/clang/test/Modules/dependency-gen.m +++ b/clang/test/Modules/dependency-gen.m @@ -4,18 +4,18 @@ // RUN: %clang_cc1 -x objective-c -isystem %S/Inputs/System/usr/include -dependency-file %t.d.1 -MT %s.o -I %S/Inputs -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp %s // RUN: FileCheck %s < %t.d.1 // CHECK: dependency-gen.m -// CHECK: Inputs{{.}}module.map +// CHECK: Inputs{{.}}module.modulemap // CHECK: Inputs{{.}}diamond_top.h -// CHECK-NOT: usr{{.}}include{{.}}module.map +// CHECK-NOT: usr{{.}}include{{.}}module.modulemap // CHECK-NOT: stdint.h // RUN: %clang_cc1 -x objective-c -isystem %S/Inputs/System/usr/include -dependency-file %t.d.2 -MT %s.o -I %S/Inputs -sys-header-deps -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp %s // RUN: FileCheck %s -check-prefix=CHECK-SYS < %t.d.2 // CHECK-SYS: dependency-gen.m -// CHECK-SYS: Inputs{{.}}module.map +// CHECK-SYS: Inputs{{.}}module.modulemap // CHECK-SYS: Inputs{{.}}diamond_top.h -// CHECK-SYS: usr{{.}}include{{.}}module.map +// CHECK-SYS: usr{{.}}include{{.}}module.modulemap // CHECK-SYS: stdint.h #import "diamond_top.h" diff --git a/clang/test/Modules/diag-flags.cpp b/clang/test/Modules/diag-flags.cpp index 0db8b4412673d389f31de059a0e7e7a7dc736ac2..9301477b4591d8ba28d8b6534f788f518269bf18 100644 --- a/clang/test/Modules/diag-flags.cpp +++ b/clang/test/Modules/diag-flags.cpp @@ -1,32 +1,32 @@ // RUN: rm -rf %t // // For an implicit module, all that matters are the warning flags in the user. -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -std=c++20 +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_flags -x c++ %S/Inputs/module.modulemap -std=c++20 // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -DLOCAL_WARNING -Wpadded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DERROR -DLOCAL_ERROR -Wpadded -Werror // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DERROR -DLOCAL_ERROR -Werror=padded // // For an explicit module, all that matters are the warning flags in the module build. -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -std=c++20 -o %t/nodiag.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.modulemap -std=c++20 -o %t/nodiag.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -fmodule-file=%t/nodiag.pcm -Wpadded -DLOCAL_WARNING // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -fmodule-file=%t/nodiag.pcm -Werror -Wpadded -DLOCAL_ERROR // -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -std=c++20 -o %t/warning.pcm -Wpadded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.modulemap -std=c++20 -o %t/warning.pcm -Wpadded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -fmodule-file=%t/warning.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -fmodule-file=%t/warning.pcm -Werror=padded -DLOCAL_ERROR // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -fmodule-file=%t/warning.pcm -Werror // -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -std=c++20 -o %t/werror-no-error.pcm -Werror -Wpadded -Wno-error=padded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.modulemap -std=c++20 -o %t/werror-no-error.pcm -Werror -Wpadded -Wno-error=padded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -fmodule-file=%t/werror-no-error.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -fmodule-file=%t/werror-no-error.pcm -Wno-padded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DWARNING -fmodule-file=%t/werror-no-error.pcm -Werror=padded -DLOCAL_ERROR // -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -std=c++20 -o %t/error.pcm -Werror=padded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.modulemap -std=c++20 -o %t/error.pcm -Werror=padded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DERROR -fmodule-file=%t/error.pcm -Wno-padded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DERROR -fmodule-file=%t/error.pcm -Wno-error=padded // -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -std=c++20 -o %t/werror.pcm -Werror -Wpadded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.modulemap -std=c++20 -o %t/werror.pcm -Werror -Wpadded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DERROR -fmodule-file=%t/werror.pcm -Wno-error // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DERROR -fmodule-file=%t/werror.pcm -Wno-padded diff --git a/clang/test/Modules/diag-pragma.c b/clang/test/Modules/diag-pragma.c index 63be4bf93afcfb57d091ee91c61262958d275c48..80224629a1c81e02e8de5e6dc55201a838ad96d8 100644 --- a/clang/test/Modules/diag-pragma.c +++ b/clang/test/Modules/diag-pragma.c @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s // FIXME: When we have a syntax for modules in C, use that. diff --git a/clang/test/Modules/diag-pragma.cpp b/clang/test/Modules/diag-pragma.cpp index b1f10365e2356cb2b1f19d9d383a7725b99b1406..4b6318045372a8e74911ca118f507927400a0f97 100644 --- a/clang/test/Modules/diag-pragma.cpp +++ b/clang/test/Modules/diag-pragma.cpp @@ -1,7 +1,7 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -std=c++20 +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma -x c++ %S/Inputs/module.modulemap -std=c++20 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -std=c++20 -o %t/explicit.pcm -Werror=string-plus-int +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_pragma -x c++ %S/Inputs/module.modulemap -std=c++20 -o %t/explicit.pcm -Werror=string-plus-int // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -std=c++20 -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm #include "diag_pragma.h" diff --git a/clang/test/Modules/diamond-pch.c b/clang/test/Modules/diamond-pch.c index 41cfd9c53b85a075378338765be5e2aff530e04d..b60420cb8ed0b3e3db4efabfc27b29a0da5ca622 100644 --- a/clang/test/Modules/diamond-pch.c +++ b/clang/test/Modules/diamond-pch.c @@ -1,8 +1,8 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-pch -fmodules-cache-path=%t -I %S/Inputs -o %t.pch %S/Inputs/diamond.h // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -I %S/Inputs -verify // FIXME: When we have a syntax for modules in C, use that. diff --git a/clang/test/Modules/diamond.c b/clang/test/Modules/diamond.c index c2e009fbc1d98aa9139882f80b17f0f69ec12e25..1e0641cafd87b0a7028407fe91d6765081b625fc 100644 --- a/clang/test/Modules/diamond.c +++ b/clang/test/Modules/diamond.c @@ -1,8 +1,8 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_top %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s -verify // FIXME: When we have a syntax for modules in C, use that. diff --git a/clang/test/Modules/extern_c_bad.cpp b/clang/test/Modules/extern_c_bad.cpp index c34416a4b71563fdccc2cfa1a19002fd17da146c..cd4e5abdfbfa73ec1357de3af556e6ffd1207790 100644 --- a/clang/test/Modules/extern_c_bad.cpp +++ b/clang/test/Modules/extern_c_bad.cpp @@ -1,2 +1,2 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -x c++ -emit-module -fmodules-cache-path=%t -fmodule-name=c_library_bad %S/Inputs/module.map +// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -x c++ -emit-module -fmodules-cache-path=%t -fmodule-name=c_library_bad %S/Inputs/module.modulemap diff --git a/clang/test/Modules/fmodules-validate-once-per-build-session.c b/clang/test/Modules/fmodules-validate-once-per-build-session.c index 7ab6f78c194fdb0f04d7908e4166f380aa47e4ab..c3e67834802b64781999985515dc46c3f52c45f6 100644 --- a/clang/test/Modules/fmodules-validate-once-per-build-session.c +++ b/clang/test/Modules/fmodules-validate-once-per-build-session.c @@ -11,8 +11,8 @@ // foo.h as a system header. // RUN: echo 'void meow(void);' > %t/Inputs/foo.h // RUN: echo 'void woof(void);' > %t/Inputs/bar.h -// RUN: echo 'module Foo { header "foo.h" }' > %t/Inputs/module.map -// RUN: echo 'extern module Bar "bar.modulemap"' >> %t/Inputs/module.map +// RUN: echo 'module Foo { header "foo.h" }' > %t/Inputs/module.modulemap +// RUN: echo 'extern module Bar "bar.modulemap"' >> %t/Inputs/module.modulemap // RUN: echo 'module Bar { header "bar.h" }' > %t/Inputs/bar.modulemap // === @@ -53,7 +53,7 @@ // === // Use the module, and make sure that we did not recompile it if foo.h or -// module.map are system files, even though the sources changed. +// module.modulemap are system files, even though the sources changed. // RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s // RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s // RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp diff --git a/clang/test/Modules/fsystem-module.m b/clang/test/Modules/fsystem-module.m index 6ef91b762b0f4eba12bf326dee2a6fe9e280bcf6..7eeb35d18f0a1192d1563ec94288ea62b02056cd 100644 --- a/clang/test/Modules/fsystem-module.m +++ b/clang/test/Modules/fsystem-module.m @@ -6,13 +6,13 @@ // RUN: not %clang_cc1 -fmodules -I %S/Inputs \ // RUN: -emit-module -fmodule-name=warning -pedantic -Werror \ -// RUN: %S/Inputs/module.map -o %t.dir/warning.pcm +// RUN: %S/Inputs/module.modulemap -o %t.dir/warning.pcm // RUN: %clang_cc1 -fmodules -I %S/Inputs \ // RUN: -emit-module -fmodule-name=warning -pedantic -Werror \ -// RUN: %S/Inputs/module.map -o %t.dir/warning-system.pcm -fsystem-module +// RUN: %S/Inputs/module.modulemap -o %t.dir/warning-system.pcm -fsystem-module // RUN: not %clang_cc1 -fmodules -I %S/Inputs \ // RUN: -emit-module -fmodule-name=warning -pedantic -Werror \ -// RUN: %S/Inputs/module.map -o %t.dir/warning-system.pcm -fsystem-module \ +// RUN: %S/Inputs/module.modulemap -o %t.dir/warning-system.pcm -fsystem-module \ // RUN: -Wsystem-headers diff --git a/clang/test/Modules/irgen.c b/clang/test/Modules/irgen.c index 92bd855c90753ff1612a7d65c827109c869c464d..a1e07eb1d87e9a911486ee6bb628f52bb633c918 100644 --- a/clang/test/Modules/irgen.c +++ b/clang/test/Modules/irgen.c @@ -1,6 +1,6 @@ // REQUIRES: x86-registered-target // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=irgen -triple x86_64-apple-darwin10 %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=irgen -triple x86_64-apple-darwin10 %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s // FIXME: When we have a syntax for modules in C, use that. diff --git a/clang/test/Modules/linkage-merge.m b/clang/test/Modules/linkage-merge.m index e7b9e5cec1367810cb430f16da1bf981f59b290d..c38524fa577beb4238af924138bbf950f7637b47 100644 --- a/clang/test/Modules/linkage-merge.m +++ b/clang/test/Modules/linkage-merge.m @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -w %s -verify // Test redeclarations of functions where the original declaration is diff --git a/clang/test/Modules/load_failure.c b/clang/test/Modules/load_failure.c index 6e63ba2adb196eb1cc53f233df68bec939facf17..3a8d29597348da9d1f5429bbea28a3affcf1bb22 100644 --- a/clang/test/Modules/load_failure.c +++ b/clang/test/Modules/load_failure.c @@ -7,7 +7,7 @@ #endif // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -fdisable-module-hash -emit-module -fmodule-name=load_failure %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -fdisable-module-hash -emit-module -fmodule-name=load_failure %S/Inputs/module.modulemap // RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -I %S/Inputs -fdisable-module-hash %s -DNONEXISTENT 2>&1 | FileCheck -check-prefix=CHECK-NONEXISTENT %s // CHECK-NONEXISTENT: load_failure.c:2:9: fatal error: module 'load_nonexistent' not found diff --git a/clang/test/Modules/lookup.cpp b/clang/test/Modules/lookup.cpp index e847d78b274f1fffe76b6f3a2016b1147324c1c0..95c30bf3eedffec7e810b4d13d8eeccbc30c03e4 100644 --- a/clang/test/Modules/lookup.cpp +++ b/clang/test/Modules/lookup.cpp @@ -24,8 +24,8 @@ void f() { } // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -emit-module -fmodules-cache-path=%t -fmodule-name=lookup_left_cxx %S/Inputs/module.map -verify -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -emit-module -fmodules-cache-path=%t -fmodule-name=lookup_right_cxx %S/Inputs/module.map -verify +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -emit-module -fmodules-cache-path=%t -fmodule-name=lookup_left_cxx %S/Inputs/module.modulemap -verify +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -emit-module -fmodules-cache-path=%t -fmodule-name=lookup_right_cxx %S/Inputs/module.modulemap -verify // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s -verify // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ast-print -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix=CHECK-PRINT %s // FIXME: When we have a syntax for modules in C++, use that. diff --git a/clang/test/Modules/lookup.m b/clang/test/Modules/lookup.m index 0e09bfdd7fd95732c087b277c097a5b519e42075..33e0408d8481df5ecdc60ed6f6c91b5c2e3bcc90 100644 --- a/clang/test/Modules/lookup.m +++ b/clang/test/Modules/lookup.m @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -I %S/Inputs -verify %s // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -ast-print -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix=CHECK-PRINT %s diff --git a/clang/test/Modules/merge-concepts.cppm b/clang/test/Modules/merge-concepts.cppm index 9b611bc2f1b5e8ca9788149cab9db0bb0bdabd3a..f8a763adaff661a53e6168691d9d72695d0da4e8 100644 --- a/clang/test/Modules/merge-concepts.cppm +++ b/clang/test/Modules/merge-concepts.cppm @@ -24,16 +24,16 @@ // // RUN: rm -f %t/foo.pcm // RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \ -// RUN: -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only +// RUN: -fmodule-map-file=%t/module.modulemap %t/Use7.cpp -verify -fsyntax-only // RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \ -// RUN: -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only +// RUN: -fmodule-map-file=%t/module.modulemap %t/Use7.cpp -verify -fsyntax-only // Testing module map modules with named modules. -// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.map \ +// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.modulemap \ // RUN: %t/A.cppm -o %t/A.pcm // RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \ -// RUN: -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only +// RUN: -fmodule-map-file=%t/module.modulemap %t/Use7.cpp -verify -fsyntax-only // RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \ -// RUN: -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only +// RUN: -fmodule-map-file=%t/module.modulemap %t/Use7.cpp -verify -fsyntax-only // //--- foo.h @@ -158,7 +158,7 @@ template void foo() requires same_as {} -//--- module.map +//--- module.modulemap module "foo" { export * header "foo.h" diff --git a/clang/test/Modules/missing-header.m b/clang/test/Modules/missing-header.m index d865078e3a2f84535fec88a448730df480806d17..c162e1b5f08b3ca893bd9673dea5fe03ab6c7db1 100644 --- a/clang/test/Modules/missing-header.m +++ b/clang/test/Modules/missing-header.m @@ -9,5 +9,5 @@ // CHECK-NOT: missing_unavailable_headers @import missing_headers; -// CHECK: module.map:15:27: error: header 'missing.h' not found +// CHECK: module.modulemap:15:27: error: header 'missing.h' not found // CHECK: could not build module 'missing_headers' diff --git a/clang/test/Modules/modify-module.m b/clang/test/Modules/modify-module.m index d59a4799104ff1ae7e557a678e5ef7c266f9da79..903bf4018b01af3127adde6770f3d9cfe693721b 100644 --- a/clang/test/Modules/modify-module.m +++ b/clang/test/Modules/modify-module.m @@ -5,7 +5,7 @@ // RUN: mkdir -p %t/include // RUN: cat %S/Inputs/Modified/A.h > %t/include/A.h // RUN: cat %S/Inputs/Modified/B.h > %t/include/B.h -// RUN: cat %S/Inputs/Modified/module.map > %t/include/module.map +// RUN: cat %S/Inputs/Modified/module.modulemap > %t/include/module.modulemap // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -I %t/include %s -verify // RUN: echo '' >> %t/include/B.h // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -I %t/include %s -verify diff --git a/clang/test/Modules/module-file-home-is-cwd.m b/clang/test/Modules/module-file-home-is-cwd.m index a3875d578bb60354ded416a7c579597709a03a11..13495ebf06fb7b6625ef8382e5dac4664297d293 100644 --- a/clang/test/Modules/module-file-home-is-cwd.m +++ b/clang/test/Modules/module-file-home-is-cwd.m @@ -2,13 +2,13 @@ // RUN: cd %S // RUN: %clang_cc1 -x objective-c -fmodules -fno-implicit-modules \ // RUN: -fmodule-file-home-is-cwd -fmodule-name=libA -emit-module \ -// RUN: -fmodules-embed-all-files %S/Inputs/normal-module-map/module.map \ +// RUN: -fmodules-embed-all-files %S/Inputs/normal-module-map/module.modulemap \ // RUN: -o %t/mod.pcm // RUN: llvm-bcanalyzer --dump --disable-histogram %t/mod.pcm | FileCheck %s // RUN: llvm-bcanalyzer --dump --disable-histogram %t/mod.pcm | FileCheck %s --check-prefix=INPUT // CHECK-NOT: MODULE_DIRECTORY -// INPUT: blob data = 'Inputs{{/|\\}}normal-module-map{{/|\\}}module.map' +// INPUT: blob data = 'Inputs{{/|\\}}normal-module-map{{/|\\}}module.modulemap' // INPUT: blob data = 'Inputs{{/|\\}}normal-module-map{{/|\\}}a2.h' // INPUT: blob data = 'Inputs{{/|\\}}normal-module-map{{/|\\}}a1.h' @@ -17,7 +17,7 @@ // RUN: cd %t // RUN: %clang_cc1 -x objective-c -fmodules -fno-implicit-modules -debug-info-kind=limited \ // RUN: -debugger-tuning=lldb -dwarf-ext-refs -fmodule-file-home-is-cwd \ -// RUN: -fmodule-map-file=%S/Inputs/normal-module-map/module.map \ +// RUN: -fmodule-map-file=%S/Inputs/normal-module-map/module.modulemap \ // RUN: -fmodule-file=libA=mod.pcm -emit-llvm -o %t-mod.ll %s // RUN: cat %t-mod.ll | FileCheck %s --check-prefix=SKELETON diff --git a/clang/test/Modules/module-private.cpp b/clang/test/Modules/module-private.cpp index 2848226ba067c63228e5b527a728dd0dbb2896b4..4036c345ef3c935af789c74fa756ecdc2439debf 100644 --- a/clang/test/Modules/module-private.cpp +++ b/clang/test/Modules/module-private.cpp @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -std=c++17 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_left -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -std=c++17 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_right -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -std=c++17 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_left -emit-module %S/Inputs/module.modulemap +// RUN: %clang_cc1 -std=c++17 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_right -emit-module %S/Inputs/module.modulemap // RUN: %clang_cc1 -std=c++17 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s -verify // FIXME: When we have a syntax for modules in C++, use that. diff --git a/clang/test/Modules/module_file_info.m b/clang/test/Modules/module_file_info.m index 179c7f35df4ac06eac766d1ff341a9c297830d02..f5ba25d54b97c5076b707f0f7a86068b07bd6086 100644 --- a/clang/test/Modules/module_file_info.m +++ b/clang/test/Modules/module_file_info.m @@ -16,7 +16,7 @@ // CHECK: Generated by this Clang: // CHECK: Module name: DependsOnModule -// CHECK: Module map file: {{.*}}DependsOnModule.framework{{[/\\]}}module.map +// CHECK: Module map file: {{.*}}DependsOnModule.framework{{[/\\]}}Modules{{[/\\]}}module.modulemap // CHECK: Imports module 'Module': {{.*}}Module{{.*}}.pcm // CHECK: Language options: @@ -47,10 +47,10 @@ // MACROS: Predefined macros: // MACROS-NEXT: -DBLARG // MACROS-NEXT: -DWIBBLE=WOBBLE -// CHECK: Input file: {{.*}}module.map -// CHECK-NEXT: Input file: {{.*}}module_private.map +// CHECK: Input file: {{.*}}module.modulemap +// CHECK-NEXT: Input file: {{.*}}module.private.modulemap // CHECK-NEXT: Input file: {{.*}}DependsOnModule.h -// CHECK-NEXT: Input file: {{.*}}module.map +// CHECK-NEXT: Input file: {{.*}}module.modulemap // CHECK-NEXT: Input file: {{.*}}other.h // CHECK-NEXT: Input file: {{.*}}not_cxx.h // CHECK-NEXT: Input file: {{.*}}not_coroutines.h diff --git a/clang/test/Modules/modulemap-locations.m b/clang/test/Modules/modulemap-locations.m index e5738e105263ac81be9bc50ebe7ac41dfcaadd6c..330a03d1fb6335ca028e260993a5b3b61251d759 100644 --- a/clang/test/Modules/modulemap-locations.m +++ b/clang/test/Modules/modulemap-locations.m @@ -2,9 +2,13 @@ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/ModuleMapLocations/Module_ModuleMap -I %S/Inputs/ModuleMapLocations/Both -F %S/Inputs/ModuleMapLocations -I %S/Inputs/ModuleMapLocations -F %S/Inputs -x objective-c -fsyntax-only %s -verify -Wno-private-module // regular +@import module_map; // expected-warning@*{{as a module map name is deprecated, rename it to module.modulemap}} + // expected-warning@*{{as a module map name is deprecated, rename it to module.private.modulemap}} @import module_modulemap; @import both; // framework +@import Module_Map_F; // expected-warning@*{{as a module map name is deprecated, rename it to module.modulemap in the 'Modules' directory of the framework}} +@import Module_Map_F; // expected-warning@*{{as a module map name is deprecated, rename it to module.private.modulemap in the 'Modules' directory of the framework}} @import Module_ModuleMap_F; @import Module_ModuleMap_F.Private; @import Both_F; diff --git a/clang/test/Modules/no-stale-modtime.m b/clang/test/Modules/no-stale-modtime.m index c7ff21c22a9f561659966736974a497c710454f2..92c18ac591addf5ed1f8819f5c30c36cf404a499 100644 --- a/clang/test/Modules/no-stale-modtime.m +++ b/clang/test/Modules/no-stale-modtime.m @@ -11,9 +11,9 @@ // RUN: echo '// top' > %t/t.h-1 // RUN: cat %t/t.h-1 > %t/t.h -// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.map-1 -// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > %t/module.map-2 -// RUN: cat %t/module.map-1 %t/module.map-2 > %t/module.map +// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.modulemap-1 +// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > %t/module.modulemap-2 +// RUN: cat %t/module.modulemap-1 %t/module.modulemap-2 > %t/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \ // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \ diff --git a/clang/test/Modules/objc-at-keyword.m b/clang/test/Modules/objc-at-keyword.m index 0e058a309017a018a7fceb52a9169548e81354a0..b4136cfecbd07f75176bd4a2e3968abbefe5bbd1 100644 --- a/clang/test/Modules/objc-at-keyword.m +++ b/clang/test/Modules/objc-at-keyword.m @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -x objective-c -fmodule-name=objcAtKeywordMissingEnd -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=Empty -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -x objective-c -fmodule-name=objcAtKeywordMissingEnd -emit-module %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=Empty -emit-module %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -I %S/Inputs %s @interface X // expected-note {{class started here}} diff --git a/clang/test/Modules/objc-categories.m b/clang/test/Modules/objc-categories.m index 8bc73a29c51cb27dec9a025779b9b0f618cee1a3..a2f331332c90fa3047fba34bf64157193d47c7b6 100644 --- a/clang/test/Modules/objc-categories.m +++ b/clang/test/Modules/objc-categories.m @@ -1,9 +1,9 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_top -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_left -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_right -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_bottom -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_other -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_top -emit-module %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_left -emit-module %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_right -emit-module %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_bottom -emit-module %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=category_other -emit-module %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify @import category_bottom; diff --git a/clang/test/Modules/objc-type-param.m b/clang/test/Modules/objc-type-param.m index 3417d62b25ffb08f97a4e133eac063aaccbde395..cf6008768cbe53efca817ccf6b2ddc8c5ff97b06 100644 --- a/clang/test/Modules/objc-type-param.m +++ b/clang/test/Modules/objc-type-param.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=objc_type_param -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=objc_type_param -emit-module %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify @import objc_type_param; diff --git a/clang/test/Modules/objc_redef.m b/clang/test/Modules/objc_redef.m index 2e57f41bc66247210bde6dbc087468447aed4a6a..b2a75140a76b84476dc8974f57e5a9bc35a38909 100644 --- a/clang/test/Modules/objc_redef.m +++ b/clang/test/Modules/objc_redef.m @@ -6,8 +6,8 @@ int test(id x) { } // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=weird_objc %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_left %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=weird_objc %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify // expected-no-diagnostics diff --git a/clang/test/Modules/odr_hash-blocks.cpp b/clang/test/Modules/odr_hash-blocks.cpp index 512c659f841e491bcae8182c0e408ce8e17a16cc..b1e62a1cf0b990948e59b60f40a477edd70ed7b9 100644 --- a/clang/test/Modules/odr_hash-blocks.cpp +++ b/clang/test/Modules/odr_hash-blocks.cpp @@ -17,12 +17,12 @@ // RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %t/Inputs/second.h // Build module map file -// RUN: echo "module FirstModule {" >> %t/Inputs/module.map -// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map -// RUN: echo "module SecondModule {" >> %t/Inputs/module.map -// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap +// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap // Run test // RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ diff --git a/clang/test/Modules/odr_hash-gnu.cpp b/clang/test/Modules/odr_hash-gnu.cpp index f87b2b841f905f5a1d68f683fbd4fe1e86d7552c..a212118a39a8a9740582bad0b0bfcab4428f36bf 100644 --- a/clang/test/Modules/odr_hash-gnu.cpp +++ b/clang/test/Modules/odr_hash-gnu.cpp @@ -17,12 +17,12 @@ // RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/second.h // Build module map file -// RUN: echo "module FirstModule {" >> %t/Inputs/module.map -// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map -// RUN: echo "module SecondModule {" >> %t/Inputs/module.map -// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap +// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap // Run test // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=gnu++11 diff --git a/clang/test/Modules/odr_hash-vector.cpp b/clang/test/Modules/odr_hash-vector.cpp index ee59cb617c1a67d4ff7aeb6341b0f439fe879bc1..e2da431a7325566c8101976434435398094e1786 100644 --- a/clang/test/Modules/odr_hash-vector.cpp +++ b/clang/test/Modules/odr_hash-vector.cpp @@ -17,12 +17,12 @@ // RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 %t/Inputs/second.h -fzvector // Build module map file -// RUN: echo "module FirstModule {" >> %t/Inputs/module.map -// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map -// RUN: echo "module SecondModule {" >> %t/Inputs/module.map -// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap +// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap // Run test // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++11 -fzvector diff --git a/clang/test/Modules/odr_hash.cl b/clang/test/Modules/odr_hash.cl index d4af1cea6e2654ab62700395d9a6e381db39b8ea..474da6e62f159750558c506bdfd03d1505bb9106 100644 --- a/clang/test/Modules/odr_hash.cl +++ b/clang/test/Modules/odr_hash.cl @@ -17,12 +17,12 @@ // RUN: %clang_cc1 -fsyntax-only -x c++ %t/Inputs/second.h -cl-std=CL2.0 // Build module map file -// RUN: echo "module FirstModule {" >> %t/Inputs/module.map -// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map -// RUN: echo "module SecondModule {" >> %t/Inputs/module.map -// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap +// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap // Run test // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -cl-std=CL2.0 diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp index 7954a1f5f2e50be4656a32daf8a5b3920af26a76..220ef767df849aac717cb926dd8ae5c698f03399 100644 --- a/clang/test/Modules/odr_hash.cpp +++ b/clang/test/Modules/odr_hash.cpp @@ -17,12 +17,12 @@ // RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/second.h // Build module map file -// RUN: echo "module FirstModule {" >> %t/Inputs/module.map -// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map -// RUN: echo "module SecondModule {" >> %t/Inputs/module.map -// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap +// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap // Run test // RUN: %clang_cc1 -triple x86_64-linux-gnu -x c++ -std=c++1z \ diff --git a/clang/test/Modules/odr_hash.mm b/clang/test/Modules/odr_hash.mm index 9c6454a790edb8e10f47ae2240bdb22bc9dafc41..512c8adc15924a17ce197da450d4ddcb6c8adcdd 100644 --- a/clang/test/Modules/odr_hash.mm +++ b/clang/test/Modules/odr_hash.mm @@ -17,12 +17,12 @@ // RUN: %clang_cc1 -fsyntax-only -x objective-c++ %t/Inputs/second.h -fblocks -fobjc-arc // Build module map file -// RUN: echo "module FirstModule {" >> %t/Inputs/module.map -// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map -// RUN: echo "module SecondModule {" >> %t/Inputs/module.map -// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map -// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap +// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap +// RUN: echo "}" >> %t/Inputs/module.modulemap // Run test // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c++ -I%t/Inputs -verify %s -fblocks -fobjc-arc diff --git a/clang/test/Modules/pr64755.cppm b/clang/test/Modules/pr64755.cppm index 75ef843154610de1fa2bdfb409d72d3243d47a6e..2d656868eb60bbed8938271b6ee7955dd797cd91 100644 --- a/clang/test/Modules/pr64755.cppm +++ b/clang/test/Modules/pr64755.cppm @@ -7,6 +7,11 @@ // RUN: %clang_cc1 -std=c++20 %t/use.cpp -fmodule-file=a0=%t/a0.pcm -verify -fsyntax-only // RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t -verify -fsyntax-only +// RUN: %clang_cc1 -std=c++20 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%t -fmodule-name=a0 -x objective-c++ -emit-module %t/module.modulemap -o %t/a0.pcm +// RUN: %clang_cc1 -std=c++20 -x objective-c++ %t/use_obj.cpp -fmodule-file=%t/a0.pcm -verify -fsyntax-only +// RUN: %clang_cc1 -std=c++20 -x objective-c++ %t/use_obj.cpp -fmodule-file=a0=%t/a0.pcm -verify -fsyntax-only +// RUN: %clang_cc1 -std=c++20 -x objective-c++ %t/use_obj.cpp -fprebuilt-module-path=%t -verify -fsyntax-only + //--- module.modulemap module a0 { header "a0.h" export * } @@ -15,3 +20,7 @@ void a0() {} //--- use.cpp import a0; // expected-error {{import of module 'a0' imported non C++20 importable modules}} + +//--- use_obj.cpp +// expected-no-diagnostics +@import a0; diff --git a/clang/test/Modules/pragma-pack.cpp b/clang/test/Modules/pragma-pack.cpp index 96a880c6307b0d2ad1e4055ceb9afea0fe40a557..8239cafd6907e4d5ec96e338dd61dfb717d05dc0 100644 --- a/clang/test/Modules/pragma-pack.cpp +++ b/clang/test/Modules/pragma-pack.cpp @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ // RUN: -fimplicit-module-maps -x c++ -emit-module \ // RUN: -fmodules-cache-path=%t.cache \ -// RUN: -fmodule-name=pragma_pack %S/Inputs/module.map +// RUN: -fmodule-name=pragma_pack %S/Inputs/module.modulemap // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ // RUN: -fimplicit-module-maps -x c++ -verify \ // RUN: -fmodules-cache-path=%t.cache \ @@ -11,7 +11,7 @@ // RUN: -fmodules-local-submodule-visibility \ // RUN: -fimplicit-module-maps -x c++ -emit-module \ // RUN: -fmodules-cache-path=%tlocal.cache \ -// RUN: -fmodule-name=pragma_pack %S/Inputs/module.map +// RUN: -fmodule-name=pragma_pack %S/Inputs/module.modulemap // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ // RUN: -fmodules-local-submodule-visibility \ // RUN: -fimplicit-module-maps -x c++ -verify \ diff --git a/clang/test/Modules/recursive.c b/clang/test/Modules/recursive.c index 9c03a6ac4548b049217e540d8a8598fa7f88ee25..efb21320f7768505ec22c161d64f403fad14ffcf 100644 --- a/clang/test/Modules/recursive.c +++ b/clang/test/Modules/recursive.c @@ -3,7 +3,7 @@ #include "recursive1.h" // RUN: rm -rf %t -// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=recursive1 %S/Inputs/module.map 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=recursive1 %S/Inputs/module.modulemap 2>&1 | FileCheck %s // CHECK: While building module 'recursive1'{{( imported from .*[/\]recursive.c:3)?}}: // CHECK-NEXT: While building module 'recursive2' imported from {{.*Inputs[/\]}}recursive1.h:1: diff --git a/clang/test/Modules/redecl-namespaces.mm b/clang/test/Modules/redecl-namespaces.mm index e17af86feba816acc5db89d7cee6c2159340ff9b..9732b31f2b92d2b278435a29676604f83beecae8 100644 --- a/clang/test/Modules/redecl-namespaces.mm +++ b/clang/test/Modules/redecl-namespaces.mm @@ -8,6 +8,6 @@ void test() { } // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -emit-module -fmodule-name=redecl_namespaces_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -emit-module -fmodule-name=redecl_namespaces_right %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -emit-module -fmodule-name=redecl_namespaces_left %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c++ -fmodules-cache-path=%t -emit-module -fmodule-name=redecl_namespaces_right %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -w %s -verify diff --git a/clang/test/Modules/redeclarations.m b/clang/test/Modules/redeclarations.m index e3f78f28d75c50704f04a9278e9307911e8ab32b..dacc84c6df469afabe81d899e1e49c5a7d33f9df 100644 --- a/clang/test/Modules/redeclarations.m +++ b/clang/test/Modules/redeclarations.m @@ -5,8 +5,8 @@ @end // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_left %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_right %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_left %S/Inputs/module.modulemap +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_right %S/Inputs/module.modulemap // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify // expected-no-diagnostics diff --git a/clang/test/Modules/relative-submodule-topheader.m b/clang/test/Modules/relative-submodule-topheader.m index c7c2f130768664c074c147f6ec66e7fad94e8f61..ec973a9c96893daefb99ff48acd97a8433c2e49b 100644 --- a/clang/test/Modules/relative-submodule-topheader.m +++ b/clang/test/Modules/relative-submodule-topheader.m @@ -1,5 +1,5 @@ // RUN: cd %S -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x objective-c++ -fmodule-name=std -emit-module Inputs/submodules/module.map -o %t/mod.pcm +// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x objective-c++ -fmodule-name=std -emit-module Inputs/submodules/module.modulemap -o %t/mod.pcm // RUN: llvm-bcanalyzer --dump --disable-histogram %t/mod.pcm | FileCheck %s // CHECK: blob data = 'vector.h' diff --git a/clang/test/Modules/requires-coroutines.mm b/clang/test/Modules/requires-coroutines.mm index 21b8b8b097e915e630f0b20e6fc10772b1ecef5c..c432c579fe5f2a135b70cf1acd065d145f50fb8b 100644 --- a/clang/test/Modules/requires-coroutines.mm +++ b/clang/test/Modules/requires-coroutines.mm @@ -2,5 +2,5 @@ // RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -Wno-private-module -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify @import DependsOnModule.NotCoroutines; -// expected-error@module.map:25 {{module 'DependsOnModule.Coroutines' requires feature 'coroutines'}} +// expected-error@Modules/module.modulemap:25 {{module 'DependsOnModule.Coroutines' requires feature 'coroutines'}} @import DependsOnModule.Coroutines; // expected-note {{module imported here}} diff --git a/clang/test/Modules/requires-gnuinlineasm.m b/clang/test/Modules/requires-gnuinlineasm.m index e710b6bf8d4b500a010abf2f7c5af52f617d75ad..e1900b14510794863056cb95e24fe80df0c52b7f 100644 --- a/clang/test/Modules/requires-gnuinlineasm.m +++ b/clang/test/Modules/requires-gnuinlineasm.m @@ -9,7 +9,7 @@ // RUN: -DASM_INLINE -verify #ifdef NO_ASM_INLINE -// expected-error@NeedsGNUInlineAsm.framework/module.map:4 {{module 'NeedsGNUInlineAsm.Asm' requires feature 'gnuinlineasm'}} +// expected-error@NeedsGNUInlineAsm.framework/Modules/module.modulemap:4 {{module 'NeedsGNUInlineAsm.Asm' requires feature 'gnuinlineasm'}} @import NeedsGNUInlineAsm.Asm; // expected-note {{module imported here}} #endif diff --git a/clang/test/Modules/requires.m b/clang/test/Modules/requires.m index 77f00a0e47c182590db76a0c141bb515ab0b2ea5..a47ea2b4bd0c9003884942344cb9da186c7f589f 100644 --- a/clang/test/Modules/requires.m +++ b/clang/test/Modules/requires.m @@ -2,39 +2,39 @@ // RUN: %clang_cc1 -Rmodule-include-translation -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs %s -verify -fmodule-feature custom_req1 // RUN: %clang_cc1 -Rmodule-include-translation -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs %s -verify -std=c89 -DTEST_C_FEATURES #ifndef TEST_C_FEATURES -// expected-error@DependsOnModule.framework/module.map:7 {{module 'DependsOnModule.CXX' requires feature 'cplusplus'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:7 {{module 'DependsOnModule.CXX' requires feature 'cplusplus'}} @import DependsOnModule.CXX; // expected-note {{module imported here}} @import DependsOnModule.NotCXX; -// expected-error@DependsOnModule.framework/module.map:15 {{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:15 {{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}} @import DependsOnModule.NotObjC; // expected-note {{module imported here}} @import DependsOnModule.CustomReq1; // OK -// expected-error@DependsOnModule.framework/module.map:22 {{module 'DependsOnModule.CustomReq2' requires feature 'custom_req2'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:22 {{module 'DependsOnModule.CustomReq2' requires feature 'custom_req2'}} @import DependsOnModule.CustomReq2; // expected-note {{module imported here}} @import RequiresWithMissingHeader; // OK -// expected-error@module.map:* {{module 'RequiresWithMissingHeader.HeaderBefore' requires feature 'missing'}} +// expected-error@module.modulemap:* {{module 'RequiresWithMissingHeader.HeaderBefore' requires feature 'missing'}} @import RequiresWithMissingHeader.HeaderBefore; // expected-note {{module imported here}} -// expected-error@module.map:* {{module 'RequiresWithMissingHeader.HeaderAfter' requires feature 'missing'}} +// expected-error@module.modulemap:* {{module 'RequiresWithMissingHeader.HeaderAfter' requires feature 'missing'}} @import RequiresWithMissingHeader.HeaderAfter; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:40 {{module 'DependsOnModule.CXX11' requires feature 'cplusplus11'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:40 {{module 'DependsOnModule.CXX11' requires feature 'cplusplus11'}} @import DependsOnModule.CXX11; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:43 {{module 'DependsOnModule.CXX14' requires feature 'cplusplus14'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:43 {{module 'DependsOnModule.CXX14' requires feature 'cplusplus14'}} @import DependsOnModule.CXX14; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:46 {{module 'DependsOnModule.CXX17' requires feature 'cplusplus17'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:46 {{module 'DependsOnModule.CXX17' requires feature 'cplusplus17'}} @import DependsOnModule.CXX17; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:49 {{module 'DependsOnModule.CXX20' requires feature 'cplusplus20'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:49 {{module 'DependsOnModule.CXX20' requires feature 'cplusplus20'}} @import DependsOnModule.CXX20; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:52 {{module 'DependsOnModule.CXX23' requires feature 'cplusplus23'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:52 {{module 'DependsOnModule.CXX23' requires feature 'cplusplus23'}} @import DependsOnModule.CXX23; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:55 {{module 'DependsOnModule.CXX26' requires feature 'cplusplus26'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:55 {{module 'DependsOnModule.CXX26' requires feature 'cplusplus26'}} @import DependsOnModule.CXX26; // expected-note {{module imported here}} #else -// expected-error@DependsOnModule.framework/module.map:58 {{module 'DependsOnModule.C99' requires feature 'c99'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:58 {{module 'DependsOnModule.C99' requires feature 'c99'}} @import DependsOnModule.C99; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:61 {{module 'DependsOnModule.C11' requires feature 'c11'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:61 {{module 'DependsOnModule.C11' requires feature 'c11'}} @import DependsOnModule.C11; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:64 {{module 'DependsOnModule.C17' requires feature 'c17'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:64 {{module 'DependsOnModule.C17' requires feature 'c17'}} @import DependsOnModule.C17; // expected-note {{module imported here}} -// expected-error@DependsOnModule.framework/module.map:67 {{module 'DependsOnModule.C23' requires feature 'c23'}} +// expected-error@DependsOnModule.framework/Modules/module.modulemap:67 {{module 'DependsOnModule.C23' requires feature 'c23'}} @import DependsOnModule.C23; // expected-note {{module imported here}} #endif diff --git a/clang/test/Modules/requires.mm b/clang/test/Modules/requires.mm index 4b11fcb33e1b90a0f48bf4876ce96ede12257175..943823994eeb29e129d60345e4cadef361d649a0 100644 --- a/clang/test/Modules/requires.mm +++ b/clang/test/Modules/requires.mm @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -Rmodule-include-translation -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify @import DependsOnModule.CXX; -// expected-error@module.map:11 {{module 'DependsOnModule.NotCXX' is incompatible with feature 'cplusplus'}} +// expected-error@Modules/module.modulemap:11 {{module 'DependsOnModule.NotCXX' is incompatible with feature 'cplusplus'}} @import DependsOnModule.NotCXX; // expected-note {{module imported here}} -// expected-error@module.map:15 {{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}} +// expected-error@Modules/module.modulemap:15 {{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}} @import DependsOnModule.NotObjC; // expected-note {{module imported here}} diff --git a/clang/test/Modules/target-platform-features.m b/clang/test/Modules/target-platform-features.m index 875c83a2a545bf470709ab4e1b86e752d67bac6e..08fad5b4432aff5fa6990bed56d4f313b3434112 100644 --- a/clang/test/Modules/target-platform-features.m +++ b/clang/test/Modules/target-platform-features.m @@ -4,17 +4,17 @@ // RUN: mkdir %t/cache // RUN: mkdir %t/InputsA -// RUN: echo "module RequiresMacOS {" >> %t/InputsA/module.map -// RUN: echo " requires macos" >> %t/InputsA/module.map -// RUN: echo "}" >> %t/InputsA/module.map -// RUN: echo "module RequiresNotiOS {" >> %t/InputsA/module.map -// RUN: echo " requires !ios" >> %t/InputsA/module.map -// RUN: echo "}" >> %t/InputsA/module.map -// RUN: echo "module RequiresMain {" >> %t/InputsA/module.map -// RUN: echo " module SubRequiresNotiOS {" >> %t/InputsA/module.map -// RUN: echo " requires !ios" >> %t/InputsA/module.map -// RUN: echo " }" >> %t/InputsA/module.map -// RUN: echo "}" >> %t/InputsA/module.map +// RUN: echo "module RequiresMacOS {" >> %t/InputsA/module.modulemap +// RUN: echo " requires macos" >> %t/InputsA/module.modulemap +// RUN: echo "}" >> %t/InputsA/module.modulemap +// RUN: echo "module RequiresNotiOS {" >> %t/InputsA/module.modulemap +// RUN: echo " requires !ios" >> %t/InputsA/module.modulemap +// RUN: echo "}" >> %t/InputsA/module.modulemap +// RUN: echo "module RequiresMain {" >> %t/InputsA/module.modulemap +// RUN: echo " module SubRequiresNotiOS {" >> %t/InputsA/module.modulemap +// RUN: echo " requires !ios" >> %t/InputsA/module.modulemap +// RUN: echo " }" >> %t/InputsA/module.modulemap +// RUN: echo "}" >> %t/InputsA/module.modulemap // RUN: %clang_cc1 -triple=x86_64-apple-macosx10.6 -DENABLE_DARWIN -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsA -verify %s // expected-no-diagnostics @@ -32,9 +32,9 @@ #endif // RUN: mkdir %t/InputsB -// RUN: echo "module RequiresiOSSim {" >> %t/InputsB/module.map -// RUN: echo " requires iossimulator" >> %t/InputsB/module.map -// RUN: echo "}" >> %t/InputsB/module.map +// RUN: echo "module RequiresiOSSim {" >> %t/InputsB/module.modulemap +// RUN: echo " requires iossimulator" >> %t/InputsB/module.modulemap +// RUN: echo "}" >> %t/InputsB/module.modulemap // RUN: %clang_cc1 -triple=x86_64-apple-iossimulator -DENABLE_IOSSIM -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsB %s -verify // RUN: %clang_cc1 -triple=x86_64-apple-ios-simulator -DENABLE_IOSSIM -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsB %s -verify @@ -43,15 +43,15 @@ #endif // RUN: mkdir %t/InputsC -// RUN: echo "module RequiresLinuxEABIA {" >> %t/InputsC/module.map -// RUN: echo " requires linux, gnueabi" >> %t/InputsC/module.map -// RUN: echo "}" >> %t/InputsC/module.map -// RUN: echo "module RequiresLinuxEABIB {" >> %t/InputsC/module.map -// RUN: echo " requires gnueabi" >> %t/InputsC/module.map -// RUN: echo "}" >> %t/InputsC/module.map -// RUN: echo "module RequiresLinuxEABIC {" >> %t/InputsC/module.map -// RUN: echo " requires linux" >> %t/InputsC/module.map -// RUN: echo "}" >> %t/InputsC/module.map +// RUN: echo "module RequiresLinuxEABIA {" >> %t/InputsC/module.modulemap +// RUN: echo " requires linux, gnueabi" >> %t/InputsC/module.modulemap +// RUN: echo "}" >> %t/InputsC/module.modulemap +// RUN: echo "module RequiresLinuxEABIB {" >> %t/InputsC/module.modulemap +// RUN: echo " requires gnueabi" >> %t/InputsC/module.modulemap +// RUN: echo "}" >> %t/InputsC/module.modulemap +// RUN: echo "module RequiresLinuxEABIC {" >> %t/InputsC/module.modulemap +// RUN: echo " requires linux" >> %t/InputsC/module.modulemap +// RUN: echo "}" >> %t/InputsC/module.modulemap // RUN: %clang_cc1 -triple=armv8r-none-linux-gnueabi -DENABLE_LINUXEABI -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsC %s -verify #ifdef ENABLE_LINUXEABI @@ -61,15 +61,15 @@ #endif // RUN: mkdir %t/InputsD -// RUN: echo "module RequiresWinMSVCA {" >> %t/InputsD/module.map -// RUN: echo " requires windows" >> %t/InputsD/module.map -// RUN: echo "}" >> %t/InputsD/module.map -// RUN: echo "module RequiresWinMSVCB {" >> %t/InputsD/module.map -// RUN: echo " requires windows, msvc" >> %t/InputsD/module.map -// RUN: echo "}" >> %t/InputsD/module.map -// RUN: echo "module RequiresWinMSVCC {" >> %t/InputsD/module.map -// RUN: echo " requires msvc" >> %t/InputsD/module.map -// RUN: echo "}" >> %t/InputsD/module.map +// RUN: echo "module RequiresWinMSVCA {" >> %t/InputsD/module.modulemap +// RUN: echo " requires windows" >> %t/InputsD/module.modulemap +// RUN: echo "}" >> %t/InputsD/module.modulemap +// RUN: echo "module RequiresWinMSVCB {" >> %t/InputsD/module.modulemap +// RUN: echo " requires windows, msvc" >> %t/InputsD/module.modulemap +// RUN: echo "}" >> %t/InputsD/module.modulemap +// RUN: echo "module RequiresWinMSVCC {" >> %t/InputsD/module.modulemap +// RUN: echo " requires msvc" >> %t/InputsD/module.modulemap +// RUN: echo "}" >> %t/InputsD/module.modulemap // RUN: %clang_cc1 -triple=thumbv7-unknown-windows-msvc -DENABLE_WINMSVC -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsD %s -verify #ifdef ENABLE_WINMSVC diff --git a/clang/test/Modules/timestamps.c b/clang/test/Modules/timestamps.c index 5315750b81590c5a20b51399200873af6f83e08c..50fdce6302550869633020ca0a57ae75aac3ada5 100644 --- a/clang/test/Modules/timestamps.c +++ b/clang/test/Modules/timestamps.c @@ -20,7 +20,7 @@ // CHECK-NEXT: // CHECK-NEXT: %t/Inputs/usr/include/module.map +// RUN: echo 'module Foo [system] { header "foo.h" }' > %t/Inputs/usr/include/module.modulemap //// // Build a module using a system header diff --git a/clang/test/OpenMP/atomic_compare_codegen.cpp b/clang/test/OpenMP/atomic_compare_codegen.cpp index 43607cc65ad9b5bf75c64d8da38ac00fa5b0e178..03e5081a5c1d8a1416f77ec59c6a946f478ce24d 100644 --- a/clang/test/OpenMP/atomic_compare_codegen.cpp +++ b/clang/test/OpenMP/atomic_compare_codegen.cpp @@ -13806,6 +13806,64 @@ double dxevd() { return dv; } + +double fail_dxevd() { + double dx, dv, de, dd; + +#pragma omp atomic compare capture relaxed fail(relaxed) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture acquire fail(relaxed) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture release fail(relaxed) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture acq_rel fail(relaxed) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture seq_cst fail(relaxed) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture relaxed fail(acquire) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture acquire fail(acquire) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture release fail(acquire) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture acq_rel fail(acquire) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture seq_cst fail(acquire) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture relaxed fail(seq_cst) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture acquire fail(seq_cst) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture release fail(seq_cst) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture acq_rel fail(seq_cst) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare capture seq_cst fail(seq_cst) + {if(dx == de) { dx = dv; } else { dd = dx; }} + +#pragma omp atomic compare seq_cst fail(acquire) + dx = dx < de ? de : dx; + +#pragma omp atomic compare relaxed fail(seq_cst) + dx = dx > de ? de : dx; + + return dx; +} + #endif // CHECK-LABEL: @foo( // CHECK-NEXT: entry: @@ -61966,3 +62024,89 @@ double dxevd() { // SIMD-ONLY0-NEXT: [[TMP180:%.*]] = load double, ptr [[DV]], align 8 // SIMD-ONLY0-NEXT: ret double [[TMP180]] // +// CHECK-LABEL: {{.+}}fail_dxevd{{.+}} +// CHECK-NEXT: entry: +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}}cmpxchg ptr {{.+}} monotonic monotonic{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire monotonic{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} release monotonic{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel monotonic{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}}cmpxchg ptr {{.+}} seq_cst monotonic{{.+}} +// CHECK: {{.+}}__kmpc_flush{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} monotonic acquire{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire acquire{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} release acquire{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel acquire{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} seq_cst acquire{{.+}} +// CHECK: {{.+}}__kmpc_flush{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} monotonic seq_cst{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire seq_cst{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} release seq_cst{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel seq_cst{{.+}} +// CHECK: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK-NEXT: {{.+}} bitcast double{{.+}} +// CHECK: {{.+}}cmpxchg ptr {{.+}} seq_cst seq_cst{{.+}} +// CHECK: call void {{.+}}__kmpc_flush{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} atomicrmw fmax {{.+}} seq_cst{{.+}} +// CHECK-NEXT: call void {{.+}}__kmpc_flush{{.+}} +// CHECK-NEXT: {{.+}} load double,{{.+}} +// CHECK-NEXT: {{.+}} atomicrmw fmin {{.+}} monotonic{{.+}} +// CHECK: ret double {{.+}} diff --git a/clang/test/OpenMP/map_struct_ordering.cpp b/clang/test/OpenMP/map_struct_ordering.cpp new file mode 100644 index 0000000000000000000000000000000000000000..035b39b5b12ab4ad5793b6b35a8f6b492963ed9f --- /dev/null +++ b/clang/test/OpenMP/map_struct_ordering.cpp @@ -0,0 +1,172 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" --prefix-filecheck-ir-name _ --version 4 + +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK + +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +struct Descriptor { + int *datum; + long int x; + int xi; + long int arr[1][30]; +}; + +int map_struct() { + Descriptor dat = Descriptor(); + dat.xi = 3; + dat.arr[0][0] = 1; + + #pragma omp target enter data map(to: dat.datum[:10]) map(to: dat) + + #pragma omp target + { + dat.xi = 4; + dat.datum[dat.arr[0][0]] = dat.xi; + } + + #pragma omp target exit data map(from: dat) + + return dat.xi; +} + +#endif +// CHECK-LABEL: define dso_local noundef signext i32 @_Z10map_structv( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DAT:%.*]] = alloca [[STRUCT_DESCRIPTOR:%.*]], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [3 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [3 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [3 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_SIZES:%.*]] = alloca [3 x i64], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_BASEPTRS4:%.*]] = alloca [1 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_PTRS5:%.*]] = alloca [1 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_MAPPERS6:%.*]] = alloca [1 x ptr], align 8 +// CHECK-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_BASEPTRS7:%.*]] = alloca [1 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_PTRS8:%.*]] = alloca [1 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_MAPPERS9:%.*]] = alloca [1 x ptr], align 8 +// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[DAT]], i8 0, i64 264, i1 false) +// CHECK-NEXT: [[XI:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 0, i32 2 +// CHECK-NEXT: store i32 3, ptr [[XI]], align 8 +// CHECK-NEXT: [[ARR:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1 x [30 x i64]], ptr [[ARR]], i64 0, i64 0 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [30 x i64], ptr [[ARRAYIDX]], i64 0, i64 0 +// CHECK-NEXT: store i64 1, ptr [[ARRAYIDX1]], align 8 +// CHECK-NEXT: [[DATUM:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 0, i32 0 +// CHECK-NEXT: [[DATUM2:%.*]] = getelementptr inbounds [[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: [[TMP1:%.*]] = getelementptr [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 +// CHECK-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[DAT]] to i64 +// CHECK-NEXT: [[TMP4:%.*]] = sub i64 [[TMP2]], [[TMP3]] +// CHECK-NEXT: [[TMP5:%.*]] = sdiv exact i64 [[TMP4]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTOFFLOAD_SIZES]], ptr align 8 @.offload_sizes, i64 24, i1 false) +// CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP6]], align 8 +// CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP7]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: store i64 [[TMP5]], ptr [[TMP8]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK-NEXT: store ptr null, ptr [[TMP9]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP10]], align 8 +// CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP11]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[DATUM]], ptr [[TMP13]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[ARRAYIDX3]], ptr [[TMP14]], align 8 +// CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 2 +// CHECK-NEXT: store ptr null, ptr [[TMP15]], align 8 +// CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr @[[GLOB1:[0-9]+]], i64 -1, i32 3, ptr [[TMP16]], ptr [[TMP17]], ptr [[TMP18]], ptr @.offload_maptypes, ptr null, ptr null) +// CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS4]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP19]], align 8 +// CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS5]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP20]], align 8 +// CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS6]], i64 0, i64 0 +// CHECK-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS4]], i32 0, i32 0 +// CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS5]], i32 0, i32 0 +// CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK-NEXT: store i32 2, ptr [[TMP24]], align 4 +// CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK-NEXT: store i32 1, ptr [[TMP25]], align 4 +// CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[TMP22]], ptr [[TMP26]], align 8 +// CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK-NEXT: store ptr @.offload_sizes.1, ptr [[TMP28]], align 8 +// CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP29]], align 8 +// CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK-NEXT: store ptr null, ptr [[TMP30]], align 8 +// CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK-NEXT: store i64 0, ptr [[TMP32]], align 8 +// CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK-NEXT: store i64 0, ptr [[TMP33]], align 8 +// CHECK-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK-NEXT: store [3 x i32] [i32 -1, i32 0, i32 0], ptr [[TMP34]], align 4 +// CHECK-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK-NEXT: store i32 0, ptr [[TMP36]], align 4 +// CHECK-NEXT: [[TMP37:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 -1, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10map_structv_l23.region_id, ptr [[KERNEL_ARGS]]) +// CHECK-NEXT: [[TMP38:%.*]] = icmp ne i32 [[TMP37]], 0 +// CHECK-NEXT: br i1 [[TMP38]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK: omp_offload.failed: +// CHECK-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10map_structv_l23(ptr [[DAT]]) #[[ATTR3:[0-9]+]] +// CHECK-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK: omp_offload.cont: +// CHECK-NEXT: [[TMP39:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP39]], align 8 +// CHECK-NEXT: [[TMP40:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[DAT]], ptr [[TMP40]], align 8 +// CHECK-NEXT: [[TMP41:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS9]], i64 0, i64 0 +// CHECK-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK-NEXT: [[TMP42:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 +// CHECK-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr @[[GLOB1]], i64 -1, i32 1, ptr [[TMP42]], ptr [[TMP43]], ptr @.offload_sizes.3, ptr @.offload_maptypes.4, ptr null, ptr null) +// CHECK-NEXT: [[XI10:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[DAT]], i32 0, i32 2 +// CHECK-NEXT: [[TMP44:%.*]] = load i32, ptr [[XI10]], align 8 +// CHECK-NEXT: ret i32 [[TMP44]] +// +// +// CHECK-LABEL: define internal void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10map_structv_l23( +// CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(264) [[DAT:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DAT_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[DAT]], ptr [[DAT_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DAT_ADDR]], align 8 +// CHECK-NEXT: [[XI:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: store i32 4, ptr [[XI]], align 8 +// CHECK-NEXT: [[XI1:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[XI1]], align 8 +// CHECK-NEXT: [[DATUM:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DATUM]], align 8 +// CHECK-NEXT: [[ARR:%.*]] = getelementptr inbounds [[STRUCT_DESCRIPTOR]], ptr [[TMP0]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1 x [30 x i64]], ptr [[ARR]], i64 0, i64 0 +// CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [30 x i64], ptr [[ARRAYIDX]], i64 0, i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX2]], align 8 +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[TMP3]] +// CHECK-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX3]], align 4 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal void @.omp_offloading.requires_reg( +// CHECK-SAME: ) #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @__tgt_register_requires(i64 1) +// CHECK-NEXT: ret void +// diff --git a/clang/test/OpenMP/nvptx_target_teams_ompx_bare_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_ompx_bare_codegen.cpp index 9f8046acb097034690d3d3c5b59a062c5b3e8fbe..2e6f0a9ce0169f112766ff23642079d82b53037d 100644 --- a/clang/test/OpenMP/nvptx_target_teams_ompx_bare_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_ompx_bare_codegen.cpp @@ -10,7 +10,7 @@ template tx ftemplate(int n) { tx a = 0; - #pragma omp target teams ompx_bare + #pragma omp target teams ompx_bare num_teams(1) thread_limit(32) { a = 2; } diff --git a/clang/test/OpenMP/ompx_bare_messages.c b/clang/test/OpenMP/ompx_bare_messages.c index a1b3c380285287df4c85f1b4b6b5255258a8d88f..19ceee5625feecca97f3283d71b92d1fecde3ef8 100644 --- a/clang/test/OpenMP/ompx_bare_messages.c +++ b/clang/test/OpenMP/ompx_bare_messages.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-unknown %s - // RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-unknown %s - // RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-unknown -fopenmp-targets=nvptx64 %s +// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-unknown %s +// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-unknown -fopenmp-targets=nvptx64 %s void foo() { } @@ -18,4 +18,7 @@ void bar() { #pragma omp target #pragma omp teams ompx_bare // expected-error {{unexpected OpenMP clause 'ompx_bare' in directive '#pragma omp teams'}} expected-note {{OpenMP extension clause 'ompx_bare' only allowed with '#pragma omp target teams'}} foo(); + +#pragma omp target teams ompx_bare // expected-error {{'ompx_bare' clauses requires explicit grid size via 'num_teams' and 'thread_limit' clauses}} + foo(); } diff --git a/clang/test/OpenMP/target_teams_ast_print.cpp b/clang/test/OpenMP/target_teams_ast_print.cpp index 5f1040be01a25fab0d45f08200eaaec0b756e345..8eaf4cbf2493316f16f176a28f48479df8abb0bd 100644 --- a/clang/test/OpenMP/target_teams_ast_print.cpp +++ b/clang/test/OpenMP/target_teams_ast_print.cpp @@ -111,8 +111,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: #pragma omp target teams a=2; // CHECK-NEXT: a = 2; -#pragma omp target teams ompx_bare -// CHECK-NEXT: #pragma omp target teams ompx_bare +#pragma omp target teams ompx_bare num_teams(1) thread_limit(32) +// CHECK-NEXT: #pragma omp target teams ompx_bare num_teams(1) thread_limit(32) a=3; // CHECK-NEXT: a = 3; #pragma omp target teams default(none), private(argc,b) num_teams(f) firstprivate(argv) reduction(| : c, d) reduction(* : e) thread_limit(f+g) diff --git a/clang/test/OpenMP/target_teams_codegen.cpp b/clang/test/OpenMP/target_teams_codegen.cpp index b7c7add229c148654e4b5e2d9036eb0eab150aec..8790a0fc87cbb9ea4c9f3d554b8f48ad802414ba 100644 --- a/clang/test/OpenMP/target_teams_codegen.cpp +++ b/clang/test/OpenMP/target_teams_codegen.cpp @@ -121,7 +121,7 @@ int foo(int n) { aa += 1; } - #pragma omp target teams ompx_bare + #pragma omp target teams ompx_bare num_teams(1) thread_limit(1) { a += 1; aa += 1; @@ -588,12 +588,12 @@ int bar(int n){ // CHECK1-NEXT: [[TMP116:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 9 // CHECK1-NEXT: store i64 0, ptr [[TMP116]], align 8 // CHECK1-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 10 -// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP117]], align 4 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP117]], align 4 // CHECK1-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 11 -// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP118]], align 4 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP118]], align 4 // CHECK1-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 12 // CHECK1-NEXT: store i32 0, ptr [[TMP119]], align 4 -// CHECK1-NEXT: [[TMP120:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.region_id, ptr [[KERNEL_ARGS21]]) +// CHECK1-NEXT: [[TMP120:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 1, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.region_id, ptr [[KERNEL_ARGS21]]) // CHECK1-NEXT: [[TMP121:%.*]] = icmp ne i32 [[TMP120]], 0 // CHECK1-NEXT: br i1 [[TMP121]], label [[OMP_OFFLOAD_FAILED22:%.*]], label [[OMP_OFFLOAD_CONT23:%.*]] // CHECK1: omp_offload.failed22: @@ -899,64 +899,64 @@ int bar(int n){ // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !25 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META25:![0-9]+]] +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: call void [[TMP10]](ptr [[TMP11]], ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !25 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias [[META25]] +// CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK1-NEXT: [[TMP21:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP19]], 0 -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias !25 +// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 -// CHECK1-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias !25 +// CHECK1-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 -// CHECK1-NEXT: store ptr [[TMP13]], ptr [[TMP23]], align 8, !noalias !25 +// CHECK1-NEXT: store ptr [[TMP13]], ptr [[TMP23]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 3 -// CHECK1-NEXT: store ptr [[TMP14]], ptr [[TMP24]], align 8, !noalias !25 +// CHECK1-NEXT: store ptr [[TMP14]], ptr [[TMP24]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 4 -// CHECK1-NEXT: store ptr [[TMP15]], ptr [[TMP25]], align 8, !noalias !25 +// CHECK1-NEXT: store ptr [[TMP15]], ptr [[TMP25]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 5 -// CHECK1-NEXT: store ptr @.offload_maptypes, ptr [[TMP26]], align 8, !noalias !25 +// CHECK1-NEXT: store ptr @.offload_maptypes, ptr [[TMP26]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 6 -// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8, !noalias !25 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 7 -// CHECK1-NEXT: store ptr null, ptr [[TMP28]], align 8, !noalias !25 +// CHECK1-NEXT: store ptr null, ptr [[TMP28]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 8 -// CHECK1-NEXT: store i64 0, ptr [[TMP29]], align 8, !noalias !25 +// CHECK1-NEXT: store i64 0, ptr [[TMP29]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 9 -// CHECK1-NEXT: store i64 1, ptr [[TMP30]], align 8, !noalias !25 +// CHECK1-NEXT: store i64 1, ptr [[TMP30]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 10 -// CHECK1-NEXT: store [3 x i32] [[TMP20]], ptr [[TMP31]], align 4, !noalias !25 +// CHECK1-NEXT: store [3 x i32] [[TMP20]], ptr [[TMP31]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 11 -// CHECK1-NEXT: store [3 x i32] [[TMP21]], ptr [[TMP32]], align 4, !noalias !25 +// CHECK1-NEXT: store [3 x i32] [[TMP21]], ptr [[TMP32]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 12 -// CHECK1-NEXT: store i32 0, ptr [[TMP33]], align 4, !noalias !25 +// CHECK1-NEXT: store i32 0, ptr [[TMP33]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 [[TMP18]], i32 [[TMP19]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, ptr [[KERNEL_ARGS_I]]) // CHECK1-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 // CHECK1-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__EXIT:%.*]] // CHECK1: omp_offload.failed.i: // CHECK1-NEXT: [[TMP36:%.*]] = load i16, ptr [[TMP12]], align 2 -// CHECK1-NEXT: store i16 [[TMP36]], ptr [[AA_CASTED_I]], align 2, !noalias !25 -// CHECK1-NEXT: [[TMP37:%.*]] = load i64, ptr [[AA_CASTED_I]], align 8, !noalias !25 +// CHECK1-NEXT: store i16 [[TMP36]], ptr [[AA_CASTED_I]], align 2, !noalias [[META25]] +// CHECK1-NEXT: [[TMP37:%.*]] = load i64, ptr [[AA_CASTED_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP38:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK1-NEXT: store i32 [[TMP38]], ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK1-NEXT: [[TMP39:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !25 +// CHECK1-NEXT: store i32 [[TMP38]], ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias [[META25]] +// CHECK1-NEXT: [[TMP39:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP40:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK1-NEXT: store i32 [[TMP40]], ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 8, !noalias !25 +// CHECK1-NEXT: store i32 [[TMP40]], ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias [[META25]] +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP37]], i64 [[TMP39]], i64 [[TMP41]]) #[[ATTR3]] // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__EXIT]] // CHECK1: .omp_outlined..exit: @@ -1069,15 +1069,17 @@ int bar(int n){ // CHECK1-NEXT: [[AA_ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[AA_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK1-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 // CHECK1-NEXT: store i64 [[AA]], ptr [[AA_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK1-NEXT: store i32 [[TMP0]], ptr [[A_CASTED]], align 4 -// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[A_CASTED]], align 8 -// CHECK1-NEXT: [[TMP2:%.*]] = load i16, ptr [[AA_ADDR]], align 2 -// CHECK1-NEXT: store i16 [[TMP2]], ptr [[AA_CASTED]], align 2 -// CHECK1-NEXT: [[TMP3:%.*]] = load i64, ptr [[AA_CASTED]], align 8 -// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i64 [[TMP1]], i64 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[A_CASTED]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i64, ptr [[A_CASTED]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i16, ptr [[AA_ADDR]], align 2 +// CHECK1-NEXT: store i16 [[TMP3]], ptr [[AA_CASTED]], align 2 +// CHECK1-NEXT: [[TMP4:%.*]] = load i64, ptr [[AA_CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i64 [[TMP2]], i64 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -2180,12 +2182,12 @@ int bar(int n){ // CHECK3-NEXT: [[TMP114:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 9 // CHECK3-NEXT: store i64 0, ptr [[TMP114]], align 8 // CHECK3-NEXT: [[TMP115:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 10 -// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP115]], align 4 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP115]], align 4 // CHECK3-NEXT: [[TMP116:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 11 -// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP116]], align 4 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP116]], align 4 // CHECK3-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 12 // CHECK3-NEXT: store i32 0, ptr [[TMP117]], align 4 -// CHECK3-NEXT: [[TMP118:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.region_id, ptr [[KERNEL_ARGS21]]) +// CHECK3-NEXT: [[TMP118:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 1, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.region_id, ptr [[KERNEL_ARGS21]]) // CHECK3-NEXT: [[TMP119:%.*]] = icmp ne i32 [[TMP118]], 0 // CHECK3-NEXT: br i1 [[TMP119]], label [[OMP_OFFLOAD_FAILED22:%.*]], label [[OMP_OFFLOAD_CONT23:%.*]] // CHECK3: omp_offload.failed22: @@ -2493,64 +2495,64 @@ int bar(int n){ // CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) // CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) // CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 4, !noalias !26 +// CHECK3-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META26:![0-9]+]] +// CHECK3-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: call void [[TMP10]](ptr [[TMP11]], ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !26 +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK3-NEXT: [[TMP21:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP19]], 0 -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias !26 +// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 -// CHECK3-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias !26 +// CHECK3-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 -// CHECK3-NEXT: store ptr [[TMP13]], ptr [[TMP23]], align 4, !noalias !26 +// CHECK3-NEXT: store ptr [[TMP13]], ptr [[TMP23]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 3 -// CHECK3-NEXT: store ptr [[TMP14]], ptr [[TMP24]], align 4, !noalias !26 +// CHECK3-NEXT: store ptr [[TMP14]], ptr [[TMP24]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 4 -// CHECK3-NEXT: store ptr [[TMP15]], ptr [[TMP25]], align 4, !noalias !26 +// CHECK3-NEXT: store ptr [[TMP15]], ptr [[TMP25]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 5 -// CHECK3-NEXT: store ptr @.offload_maptypes, ptr [[TMP26]], align 4, !noalias !26 +// CHECK3-NEXT: store ptr @.offload_maptypes, ptr [[TMP26]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 6 -// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 4, !noalias !26 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 7 -// CHECK3-NEXT: store ptr null, ptr [[TMP28]], align 4, !noalias !26 +// CHECK3-NEXT: store ptr null, ptr [[TMP28]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 8 -// CHECK3-NEXT: store i64 0, ptr [[TMP29]], align 8, !noalias !26 +// CHECK3-NEXT: store i64 0, ptr [[TMP29]], align 8, !noalias [[META26]] // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 9 -// CHECK3-NEXT: store i64 1, ptr [[TMP30]], align 8, !noalias !26 +// CHECK3-NEXT: store i64 1, ptr [[TMP30]], align 8, !noalias [[META26]] // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 10 -// CHECK3-NEXT: store [3 x i32] [[TMP20]], ptr [[TMP31]], align 4, !noalias !26 +// CHECK3-NEXT: store [3 x i32] [[TMP20]], ptr [[TMP31]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 11 -// CHECK3-NEXT: store [3 x i32] [[TMP21]], ptr [[TMP32]], align 4, !noalias !26 +// CHECK3-NEXT: store [3 x i32] [[TMP21]], ptr [[TMP32]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 12 -// CHECK3-NEXT: store i32 0, ptr [[TMP33]], align 4, !noalias !26 +// CHECK3-NEXT: store i32 0, ptr [[TMP33]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 [[TMP18]], i32 [[TMP19]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, ptr [[KERNEL_ARGS_I]]) // CHECK3-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 // CHECK3-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__EXIT:%.*]] // CHECK3: omp_offload.failed.i: // CHECK3-NEXT: [[TMP36:%.*]] = load i16, ptr [[TMP12]], align 2 -// CHECK3-NEXT: store i16 [[TMP36]], ptr [[AA_CASTED_I]], align 2, !noalias !26 -// CHECK3-NEXT: [[TMP37:%.*]] = load i32, ptr [[AA_CASTED_I]], align 4, !noalias !26 +// CHECK3-NEXT: store i16 [[TMP36]], ptr [[AA_CASTED_I]], align 2, !noalias [[META26]] +// CHECK3-NEXT: [[TMP37:%.*]] = load i32, ptr [[AA_CASTED_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP38:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK3-NEXT: store i32 [[TMP38]], ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP39:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !26 +// CHECK3-NEXT: store i32 [[TMP38]], ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP40:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK3-NEXT: store i32 [[TMP40]], ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP41:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !26 +// CHECK3-NEXT: store i32 [[TMP40]], ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP37]], i32 [[TMP39]], i32 [[TMP41]]) #[[ATTR3]] // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__EXIT]] // CHECK3: .omp_outlined..exit: @@ -2663,15 +2665,17 @@ int bar(int n){ // CHECK3-NEXT: [[AA_ADDR:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[A_CASTED:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[AA_CASTED:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 // CHECK3-NEXT: store i32 [[AA]], ptr [[AA_ADDR]], align 4 -// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK3-NEXT: store i32 [[TMP0]], ptr [[A_CASTED]], align 4 -// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_CASTED]], align 4 -// CHECK3-NEXT: [[TMP2:%.*]] = load i16, ptr [[AA_ADDR]], align 2 -// CHECK3-NEXT: store i16 [[TMP2]], ptr [[AA_CASTED]], align 2 -// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[AA_CASTED]], align 4 -// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i32 [[TMP1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP1]], ptr [[A_CASTED]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[A_CASTED]], align 4 +// CHECK3-NEXT: [[TMP3:%.*]] = load i16, ptr [[AA_ADDR]], align 2 +// CHECK3-NEXT: store i16 [[TMP3]], ptr [[AA_CASTED]], align 2 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[AA_CASTED]], align 4 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i32 [[TMP2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -3613,16 +3617,18 @@ int bar(int n){ // CHECK9-NEXT: [[AA_ADDR:%.*]] = alloca i64, align 8 // CHECK9-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK9-NEXT: [[AA_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 // CHECK9-NEXT: store i64 [[A]], ptr [[A_ADDR]], align 8 // CHECK9-NEXT: store i64 [[AA]], ptr [[AA_ADDR]], align 8 -// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK9-NEXT: store i32 [[TMP0]], ptr [[A_CASTED]], align 4 -// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[A_CASTED]], align 8 -// CHECK9-NEXT: [[TMP2:%.*]] = load i16, ptr [[AA_ADDR]], align 2 -// CHECK9-NEXT: store i16 [[TMP2]], ptr [[AA_CASTED]], align 2 -// CHECK9-NEXT: [[TMP3:%.*]] = load i64, ptr [[AA_CASTED]], align 8 -// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i64 [[TMP1]], i64 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP1]], ptr [[A_CASTED]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i64, ptr [[A_CASTED]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i16, ptr [[AA_ADDR]], align 2 +// CHECK9-NEXT: store i16 [[TMP3]], ptr [[AA_CASTED]], align 2 +// CHECK9-NEXT: [[TMP4:%.*]] = load i64, ptr [[AA_CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i64 [[TMP2]], i64 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -4172,16 +4178,18 @@ int bar(int n){ // CHECK11-NEXT: [[AA_ADDR:%.*]] = alloca i32, align 4 // CHECK11-NEXT: [[A_CASTED:%.*]] = alloca i32, align 4 // CHECK11-NEXT: [[AA_CASTED:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 4 // CHECK11-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 // CHECK11-NEXT: store i32 [[AA]], ptr [[AA_ADDR]], align 4 -// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK11-NEXT: store i32 [[TMP0]], ptr [[A_CASTED]], align 4 -// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_CASTED]], align 4 -// CHECK11-NEXT: [[TMP2:%.*]] = load i16, ptr [[AA_ADDR]], align 2 -// CHECK11-NEXT: store i16 [[TMP2]], ptr [[AA_CASTED]], align 2 -// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[AA_CASTED]], align 4 -// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i32 [[TMP1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP1]], ptr [[A_CASTED]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[A_CASTED]], align 4 +// CHECK11-NEXT: [[TMP3:%.*]] = load i16, ptr [[AA_ADDR]], align 2 +// CHECK11-NEXT: store i16 [[TMP3]], ptr [[AA_CASTED]], align 2 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[AA_CASTED]], align 4 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l124.omp_outlined, i32 [[TMP2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // // diff --git a/clang/test/PCH/modified-module-dependency.m b/clang/test/PCH/modified-module-dependency.m index 39fddb039bad621d844de4ed907dc93b8c5f884c..44c14b3a0231ca5cdbcb0c0a1a3d047209eb336f 100644 --- a/clang/test/PCH/modified-module-dependency.m +++ b/clang/test/PCH/modified-module-dependency.m @@ -2,7 +2,7 @@ // RUN: mkdir -p %t-dir // RUN: echo '@import test;' > %t-dir/prefix.h // RUN: echo 'void foo(void);' > %t-dir/test.h -// RUN: cp %S/modified-module-dependency.module.map %t-dir/module.map +// RUN: cp %S/modified-module-dependency.module.map %t-dir/module.modulemap // Precompile prefix.pch. // RUN: %clang_cc1 -x objective-c -I %t-dir -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-dir/cache -fdisable-module-hash -emit-pch %t-dir/prefix.h -o %t-dir/prefix.pch diff --git a/clang/test/PCH/pr76443.cpp b/clang/test/PCH/pr76443.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b3e23de7da0d01d3fe648ccc2749976f030546d --- /dev/null +++ b/clang/test/PCH/pr76443.cpp @@ -0,0 +1,24 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// +// RUN: %clang_cc1 -std=c++17 -emit-pch %s -o %t/h.pcm + +//--- header.h +template int stringData(const char (&...x)[Nx]) { + return 0; +} +int qt_meta_stringdata_CLASSQStyleENDCLASS = stringData( + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", ""); diff --git a/clang/test/ParserOpenACC/parse-cache-construct.c b/clang/test/ParserOpenACC/parse-cache-construct.c index 10976627ca95ce669b8f03b2a237d39d69f0e6ba..560f45423bc2b9a7bfdd201fdb12ed32a320eb0a 100644 --- a/clang/test/ParserOpenACC/parse-cache-construct.c +++ b/clang/test/ParserOpenACC/parse-cache-construct.c @@ -14,7 +14,7 @@ void func() { for (int i = 0; i < 10; ++i) { // expected-error@+3{{expected '('}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc cache clause list } @@ -25,7 +25,7 @@ void func() { } for (int i = 0; i < 10; ++i) { - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc cache() clause-list } diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c new file mode 100644 index 0000000000000000000000000000000000000000..1e05d82906aedc471f0d2ff3bd486853f8810567 --- /dev/null +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 %s -verify -fopenacc -std=c99 +// RUNX: %clang_cc1 %s -verify -fopenacc +// RUNX: %clang_cc1 %s -verify -fopenacc -x c++ + +void func() { + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc enter data finalize + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc enter data finalize finalize + + // expected-error@+2{{invalid OpenACC clause 'invalid'}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc enter data finalize invalid + + // expected-error@+2{{invalid OpenACC clause 'invalid'}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc enter data finalize invalid invalid finalize + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc enter data seq finalize + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc host_data if_present + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc host_data if_present, if_present + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop seq independent auto + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop seq, independent auto + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop seq independent, auto + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc kernels loop seq independent auto + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial loop seq, independent auto + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel loop seq independent, auto + + + // expected-error@+2{{expected identifier}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop , seq + + // expected-error@+2{{expected identifier}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc loop seq, + +} + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc routine worker, vector, seq, nohost +void bar(); + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc routine(bar) worker, vector, seq, nohost diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c index 83d9bd6070d41db083a7846a7331bd45fac0a0f4..0bb33269bbe98fce5f7744b45d1810ef7a289345 100644 --- a/clang/test/ParserOpenACC/parse-constructs.c +++ b/clang/test/ParserOpenACC/parse-constructs.c @@ -7,14 +7,13 @@ void func() { #pragma acc for(;;){} - // expected-error@+4{{expected OpenACC directive}} - // expected-error@+3{{expected clause-list or newline in OpenACC directive}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+3{{expected OpenACC directive}} + // expected-error@+2{{invalid OpenACC clause 'whatever'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc(whatever) routine // expected-error@+3{{expected OpenACC directive}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'routine'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc) routine @@ -23,12 +22,12 @@ void func() { #pragma acc invalid for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel clause list for(;;){} // expected-error@+3{{expected clause-list or newline in OpenACC directive}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel() clause list for(;;){} @@ -38,33 +37,31 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel( clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc kernels clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc data clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc enter data clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc exit data clause list for(;;){} - // expected-error@+3{{invalid OpenACC directive 'enter invalid'}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC directive 'enter invalid'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc enter invalid for(;;){} - // expected-error@+3{{invalid OpenACC directive 'exit invalid'}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC directive 'exit invalid'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc exit invalid for(;;){} @@ -72,24 +69,23 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc enter for(;;){} - // expected-error@+3{{expected identifier}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{expected identifier}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc exit } for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc host_data clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc loop clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'invalid'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel invalid clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel loop clause list for(;;){} @@ -97,14 +93,14 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel loop for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial loop clause list for(;;){} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial loop for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc kernels loop clause list for(;;){} @@ -116,48 +112,48 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic i = j; - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'garbage'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic garbage i = j; - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'garbage'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic garbage clause list i = j; // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic read i = j; - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic write clause list i = i + j; - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic update clause list i++; - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc atomic capture clause list i = j++; - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc declare clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc init clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc shutdown clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc set clause list for(;;){} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc update clause list for(;;){} @@ -166,7 +162,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine void routine_func(); -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine clause list void routine_func(); @@ -175,13 +171,13 @@ void routine_func(); // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine (func_name) // expected-error@+3{{use of undeclared identifier 'func_name'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine (func_name) clause list // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine (routine_func) -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc routine (routine_func) clause list diff --git a/clang/test/ParserOpenACC/parse-wait-construct.c b/clang/test/ParserOpenACC/parse-wait-construct.c index 9b210bc7094210464ec2aefa154ebb5ec1dfe208..8f99f4aa8f67b10dd5f0971f4948a7f1e8d4740d 100644 --- a/clang/test/ParserOpenACC/parse-wait-construct.c +++ b/clang/test/ParserOpenACC/parse-wait-construct.c @@ -6,7 +6,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait clause-list @@ -18,7 +18,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait () - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait () clause-list @@ -33,7 +33,7 @@ void func() { #pragma acc wait (devnum:) // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (devnum:) clause-list @@ -48,7 +48,7 @@ void func() { #pragma acc wait (devnum: i + j) // expected-error@+3{{expected ':'}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (devnum: i + j) clause-list @@ -60,7 +60,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (queues:) - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (queues:) clause-list @@ -72,7 +72,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (devnum: i + j:queues:) - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (devnum: i + j:queues:) clause-list @@ -87,7 +87,7 @@ void func() { #pragma acc wait (queues:devnum: i + j) // expected-error@+3{{use of undeclared identifier 'devnum'}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait (queues:devnum: i + j) clause-list @@ -98,7 +98,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(i, j, 1+1, 3.3) - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(i, j, 1+1, 3.3) clause-list @@ -113,7 +113,7 @@ void func() { #pragma acc wait(,) // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(,) clause-list @@ -131,7 +131,7 @@ void func() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(queues:i, j, 1+1, 3.3) - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(queues:i, j, 1+1, 3.3) clause-list @@ -141,7 +141,7 @@ void func() { #pragma acc wait(devnum:3:i, j, 1+1, 3.3 // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(devnum:3:i, j, 1+1, 3.3) - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(devnum:3:i, j, 1+1, 3.3) clause-list @@ -151,7 +151,7 @@ void func() { #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3 // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) - // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-error@+2{{invalid OpenACC clause 'clause'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) clause-list } diff --git a/clang/test/ParserOpenACC/unimplemented.c b/clang/test/ParserOpenACC/unimplemented.c index 2927e685d30b563c312362398c2cf9c1857d2ae1..be8e62b5811789588e5c4fbf99343de98f57566e 100644 --- a/clang/test/ParserOpenACC/unimplemented.c +++ b/clang/test/ParserOpenACC/unimplemented.c @@ -2,7 +2,7 @@ // Parser::ParseExternalDeclaration // expected-error@+3{{invalid OpenACC directive 'havent'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'implemented'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc havent implemented int foo; @@ -10,7 +10,7 @@ int foo; struct S { // Parser::ParseStructUnionBody // expected-error@+3{{invalid OpenACC directive 'havent'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'implemented'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc havent implemented int foo; @@ -19,7 +19,7 @@ struct S { void func() { // Parser::ParseStmtOrDeclarationAfterAttributes // expected-error@+3{{invalid OpenACC directive 'havent'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'implemented'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc havent implemented while(0) {} diff --git a/clang/test/ParserOpenACC/unimplemented.cpp b/clang/test/ParserOpenACC/unimplemented.cpp index 77619c9ae6551edc97d76268fe31cb3b9002060e..6ffc84a3bc09d389646ef37bc5b1ccdf095dac87 100644 --- a/clang/test/ParserOpenACC/unimplemented.cpp +++ b/clang/test/ParserOpenACC/unimplemented.cpp @@ -2,7 +2,7 @@ // Parser::ParseExternalDeclaration // expected-error@+3{{invalid OpenACC directive 'havent'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'implemented'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc havent implemented int foo; @@ -10,7 +10,7 @@ int foo; struct S { // Parser::ParseCXXClassMemberDeclarationWithPragmas // expected-error@+3{{invalid OpenACC directive 'havent'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'implemented'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc havent implemented int foo; @@ -19,7 +19,7 @@ struct S { void func() { // Parser::ParseStmtOrDeclarationAfterAttributes // expected-error@+3{{invalid OpenACC directive 'havent'}} -// expected-warning@+2{{OpenACC clause parsing not yet implemented}} +// expected-error@+2{{invalid OpenACC clause 'implemented'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc havent implemented while(false) {} diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index db89aa7b608ad5fd177e15547e7773f8493427a4..b3da54162da04b09b494eb2ccd9cdf2d74558838 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -600,6 +600,7 @@ // RUN: %clang -target aarch64-none-elf -march=armv9.1-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-V83-OR-LATER,CHECK-V85-OR-LATER %s // RUN: %clang -target aarch64-none-elf -march=armv9.2-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-V83-OR-LATER,CHECK-V85-OR-LATER %s // RUN: %clang -target aarch64-none-elf -march=armv9.3-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-V83-OR-LATER,CHECK-V85-OR-LATER %s +// RUN: %clang -target aarch64-none-elf -march=armv9.4-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-V83-OR-LATER,CHECK-V85-OR-LATER %s // RUN: %clang -target aarch64-none-elf -march=armv9.5-a -x c -E -dM %s -o - | FileCheck --check-prefixes=CHECK-V81-OR-LATER,CHECK-V83-OR-LATER,CHECK-V85-OR-LATER %s // CHECK-V81-OR-LATER: __ARM_FEATURE_ATOMICS 1 // CHECK-V85-OR-LATER: __ARM_FEATURE_BTI 1 diff --git a/clang/test/Preprocessor/pragma_module.c b/clang/test/Preprocessor/pragma_module.c index c52d42537573f6c41b146b7de9f72b25179f9cd4..2d86b989411fd70ab21d363518b10409c3495de4 100644 --- a/clang/test/Preprocessor/pragma_module.c +++ b/clang/test/Preprocessor/pragma_module.c @@ -1,9 +1,9 @@ // RUN: rm -rf %t // RUN: mkdir %t -// RUN: echo 'module foo { module a {} module b {} } module bar {} module if {}' > %t/module.map -// RUN: %clang_cc1 -fmodules -fmodule-name=if -x c %t/module.map -emit-module -o %t/if.pcm -// RUN: %clang_cc1 -E -fmodules %s -fmodule-file=%t/if.pcm -verify -fmodule-name=foo -fmodule-map-file=%t/module.map -// RUN: %clang_cc1 -E -fmodules %s -fmodule-file=%t/if.pcm -verify -fmodule-name=foo -fmodule-map-file=%t/module.map -fmodules-local-submodule-visibility -DLOCAL_VIS +// RUN: echo 'module foo { module a {} module b {} } module bar {} module if {}' > %t/module.modulemap +// RUN: %clang_cc1 -fmodules -fmodule-name=if -x c %t/module.modulemap -emit-module -o %t/if.pcm +// RUN: %clang_cc1 -E -fmodules %s -fmodule-file=%t/if.pcm -verify -fmodule-name=foo -fmodule-map-file=%t/module.modulemap +// RUN: %clang_cc1 -E -fmodules %s -fmodule-file=%t/if.pcm -verify -fmodule-name=foo -fmodule-map-file=%t/module.modulemap -fmodules-local-submodule-visibility -DLOCAL_VIS // Just checking the syntax here; the semantics are tested elsewhere. #pragma clang module import // expected-error {{expected module name}} diff --git a/clang/test/Preprocessor/predefined-arch-macros.c b/clang/test/Preprocessor/predefined-arch-macros.c index 1ae6faea77678571d8fe1c704d8258d495249f7b..27c7b4a271fee804e7ba3cc7523bc0e44af762aa 100644 --- a/clang/test/Preprocessor/predefined-arch-macros.c +++ b/clang/test/Preprocessor/predefined-arch-macros.c @@ -2515,7 +2515,7 @@ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M32 // RUN: %clang -march=grandridge -m32 -E -dM %s -o - 2>&1 \ // RUN: --target=i386 \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32,CHECK_GRR_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32 // RUN: %clang -march=arrowlake -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M32 @@ -2572,7 +2572,6 @@ // CHECK_SRF_M32: #define __PRFCHW__ 1 // CHECK_SRF_M32: #define __PTWRITE__ 1 // CHECK_SRF_M32-NOT: #define __RAOINT__ 1 -// CHECK_GRR_M32: #define __RAOINT__ 1 // CHECK_SRF_M32: #define __RDPID__ 1 // CHECK_SRF_M32: #define __RDRND__ 1 // CHECK_SRF_M32: #define __RDSEED__ 1 @@ -2618,7 +2617,7 @@ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M64 // RUN: %clang -march=grandridge -m64 -E -dM %s -o - 2>&1 \ // RUN: --target=i386 \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64,CHECK_GRR_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64 // RUN: %clang -march=arrowlake -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M64 @@ -2675,7 +2674,6 @@ // CHECK_SRF_M64: #define __PRFCHW__ 1 // CHECK_SRF_M64: #define __PTWRITE__ 1 // CHECK_SRF_M64-NOT: #define __RAOINT__ 1 -// CHECK_GRR_M64: #define __RAOINT__ 1 // CHECK_SRF_M64: #define __RDPID__ 1 // CHECK_SRF_M64: #define __RDRND__ 1 // CHECK_SRF_M64: #define __RDSEED__ 1 diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 6fc921a8c6ee155d65d9a2d762487f6392da8194..02d8d34116f804cf197acc744f68f64e1611596a 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -33,7 +33,6 @@ // CHECK-NOT: __riscv_xcvmac {{.*$}} // CHECK-NOT: __riscv_xcvmem {{.*$}} // CHECK-NOT: __riscv_xcvsimd {{.*$}} -// CHECK-NOT: __riscv_xsfcie {{.*$}} // CHECK-NOT: __riscv_xsfvcp {{.*$}} // CHECK-NOT: __riscv_xsfvfnrclipxfqf {{.*$}} // CHECK-NOT: __riscv_xsfvfwmaccqqq {{.*$}} @@ -119,7 +118,10 @@ // CHECK-NOT: __riscv_zfa {{.*$}} // CHECK-NOT: __riscv_zfbfmin {{.*$}} // CHECK-NOT: __riscv_zicfilp {{.*$}} +// CHECK-NOT: __riscv_zicfiss {{.*$}} // CHECK-NOT: __riscv_zicond {{.*$}} +// CHECK-NOT: __riscv_zimop {{.*$}} +// CHECK-NOT: __riscv_zcmop {{.*$}} // CHECK-NOT: __riscv_ztso {{.*$}} // CHECK-NOT: __riscv_zvbb {{.*$}} // CHECK-NOT: __riscv_zvbc {{.*$}} @@ -313,14 +315,6 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-XCVSIMD-EXT %s // CHECK-XCVSIMD-EXT: __riscv_xcvsimd 1000000{{$}} -// RUN: %clang --target=riscv32-unknown-linux-gnu \ -// RUN: -march=rv32ixsfcie -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-XSFCIE-EXT %s -// RUN: %clang --target=riscv64-unknown-linux-gnu \ -// RUN: -march=rv64ixsfcie -x c -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-XSFCIE-EXT %s -// CHECK-XSFCIE-EXT: __riscv_xsfcie 1000000{{$}} - // RUN: %clang --target=riscv32-unknown-linux-gnu \ // RUN: -march=rv32ixsfvcp -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-XSFVCP-EXT %s @@ -1056,12 +1050,12 @@ // CHECK-ZFBFMIN-EXT: __riscv_zfbfmin 8000{{$}} // RUN: %clang --target=riscv32 -menable-experimental-extensions \ -// RUN: -march=rv32i_zicfilp0p2 -x c -E -dM %s \ +// RUN: -march=rv32i_zicfilp0p4 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZICFILP-EXT %s // RUN: %clang --target=riscv64 -menable-experimental-extensions \ -// RUN: -march=rv64i_zicfilp0p2 -x c -E -dM %s \ +// RUN: -march=rv64i_zicfilp0p4 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZICFILP-EXT %s -// CHECK-ZICFILP-EXT: __riscv_zicfilp 2000{{$}} +// CHECK-ZICFILP-EXT: __riscv_zicfilp 4000{{$}} // RUN: %clang --target=riscv32 -menable-experimental-extensions \ // RUN: -march=rv32i_zicond1p0 -x c -E -dM %s \ @@ -1071,6 +1065,22 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-ZICOND-EXT %s // CHECK-ZICOND-EXT: __riscv_zicond 1000000{{$}} +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zimop0p1 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZIMOP-EXT %s +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zimop0p1 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZIMOP-EXT %s +// CHECK-ZIMOP-EXT: __riscv_zimop 1000{{$}} + +// RUN: %clang --target=riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zcmop0p2 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZCMOP-EXT %s +// RUN: %clang --target=riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zcmop0p2 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZCMOP-EXT %s +// CHECK-ZCMOP-EXT: __riscv_zcmop 2000{{$}} + // RUN: %clang --target=riscv32-unknown-linux-gnu -menable-experimental-extensions \ // RUN: -march=rv32iztso0p1 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZTSO-EXT %s @@ -1278,3 +1288,11 @@ // RUN: %clang --target=riscv64-unknown-linux-gnu -march=rv64i -E -dM %s \ // RUN: -munaligned-access -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST // CHECK-MISALIGNED-FAST: __riscv_misaligned_fast 1 + +// RUN: %clang -target riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32izicfiss0p4 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s +// RUN: %clang -target riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64izicfiss0p4 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s +// CHECK-ZICFISS-EXT: __riscv_zicfiss 4000{{$}} diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c index e77e09c4435188dc775e6e58ce6aa161641721cf..e63d9f0a84757632c56bd1950f9f05c4fb6abf82 100644 --- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c +++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c @@ -5,6 +5,8 @@ // REQUIRES: aarch64-registered-target #include "arm_neon.h" +#include "arm_sme_draft_spec_subject_to_change.h" +#include "arm_sve.h" int16x8_t incompat_neon_sm(int16x8_t splat) __arm_streaming { // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} @@ -20,3 +22,83 @@ int16x8_t incompat_neon_smc(int16x8_t splat) __arm_streaming_compatible { // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}} return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); } + +void incompat_sme_smc(svbool_t pg, void const *ptr) __arm_streaming_compatible __arm_shared_za { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}} + return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr); +} + +svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} + return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); +} + +__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} + return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); +} + +svuint32_t incompat_sve_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}} + return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); +} + +svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} + return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); +} + +__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}} + return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); +} + +svuint32_t incompat_sve2_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}} + return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); +} + +void incompat_sme_sm(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) __arm_shared_za { + // expected-warning@+1 {{builtin call has undefined behaviour when called from a non-streaming function}} + svmops_za32_f32_m(0, pn, pm, zn, zm); +} + +svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming { + // expected-no-warning + return svadd_n_f64_m(pg, a, b); +} + +__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) { + // expected-no-warning + return svadd_n_f64_m(pg, a, b); +} + +svfloat64_t streaming_compatible_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming_compatible { + // expected-no-warning + return svadd_n_f64_m(pg, a, b); +} + +svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming { + // expected-no-warning + return svmul_lane_s16(op1, op2, 0); +} + +__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) { + // expected-no-warning + return svmul_lane_s16(op1, op2, 0); +} + +svint16_t streaming_compatible_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming_compatible { + // expected-no-warning + return svmul_lane_s16(op1, op2, 0); +} + +svbool_t streaming_caller_ptrue(void) __arm_streaming { + // expected-no-warning + return svand_z(svptrue_b16(), svptrue_pat_b16(SV_ALL), svptrue_pat_b16(SV_VL4)); +} + +svint8_t missing_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming { + // expected-warning@+1 {{builtin call is not valid when calling from a function without active ZA state}} + return svread_hor_za8_s8_m(zd, pg, 0, slice_base); +} diff --git a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp index 1faa5638c801c2df4deabffdafbb5f9c2534338c..529d0d2d1e625e8e9b31ea3860fb3b9570cc8815 100644 --- a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp +++ b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp @@ -12,7 +12,7 @@ #include -void test_range_0_0(uint32_t slice, svbool_t pg, void *ptr) { +void test_range_0_0(uint32_t slice, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 0]}} SVE_ACLE_FUNC(svld1_hor_za8,,,)(-1, slice, pg, ptr); // expected-error@+1 {{argument value 1 is outside the valid range [0, 0]}} @@ -32,7 +32,7 @@ void test_range_0_0(uint32_t slice, svbool_t pg, void *ptr) { SVE_ACLE_FUNC(svwrite_ver_za8, _s8, _m,)(1, slice, pg, svundef_s8()); } -void test_range_0_1(uint32_t slice, svbool_t pg, void *ptr) { +void test_range_0_1(uint32_t slice, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 1]}} SVE_ACLE_FUNC(svld1_hor_za16,,,)(-1, slice, pg, ptr); // expected-error@+1 {{argument value 2 is outside the valid range [0, 1]}} @@ -52,7 +52,7 @@ void test_range_0_1(uint32_t slice, svbool_t pg, void *ptr) { SVE_ACLE_FUNC(svwrite_ver_za16, _s16, _m,)(2, slice, pg, svundef_s16()); } -void test_range_0_3(uint32_t slice, svbool_t pg, void *ptr) { +void test_range_0_3(uint32_t slice, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 3]}} SVE_ACLE_FUNC(svld1_hor_za32,,,)(-1, slice, pg, ptr); // expected-error@+1 {{argument value 4 is outside the valid range [0, 3]}} @@ -90,7 +90,7 @@ void test_range_0_3(uint32_t slice, svbool_t pg, void *ptr) { SVE_ACLE_FUNC(svusmops_za32, _u8, _m,)(-1, pg, pg, svundef_u8(), svundef_s8()); } -void test_range_0_7(uint32_t slice, svbool_t pg, void *ptr) { +void test_range_0_7(uint32_t slice, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} SVE_ACLE_FUNC(svld1_hor_za64,,,)(-1, slice, pg, ptr); // expected-error@+1 {{argument value 8 is outside the valid range [0, 7]}} @@ -133,7 +133,7 @@ void test_range_0_7(uint32_t slice, svbool_t pg, void *ptr) { SVE_ACLE_FUNC(svmops_za64, _f64, _m,)(-1, pg, pg, svundef_f64(), svundef_f64()); } -void test_range_0_15(uint32_t slice, svbool_t pg, void *ptr) { +void test_range_0_15(uint32_t slice, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} SVE_ACLE_FUNC(svld1_hor_za128,,,)(-1, slice, pg, ptr); // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} @@ -153,14 +153,14 @@ void test_range_0_15(uint32_t slice, svbool_t pg, void *ptr) { SVE_ACLE_FUNC(svwrite_ver_za128, _s8, _m,)(16, slice, pg, svundef_s8()); } -void test_range_0_255(svbool_t pg, void *ptr) { +void test_range_0_255(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { // expected-error@+1 {{argument value 256 is outside the valid range [0, 255]}} SVE_ACLE_FUNC(svzero_mask_za,,,)(256); // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 255]}} SVE_ACLE_FUNC(svzero_mask_za,,,)(-1); } -void test_constant(uint64_t u64, svbool_t pg, void *ptr) { +void test_constant(uint64_t u64, svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { SVE_ACLE_FUNC(svld1_hor_za8,,,)(u64, u64, pg, ptr); // expected-error {{argument to 'svld1_hor_za8' must be a constant integer}} SVE_ACLE_FUNC(svst1_hor_za32,,,)(u64, 0, pg, ptr); // expected-error {{argument to 'svst1_hor_za32' must be a constant integer}} SVE_ACLE_FUNC(svld1_hor_vnum_za8,,,)(u64, 0, pg, ptr, u64); // expected-error {{argument to 'svld1_hor_vnum_za8' must be a constant integer}} diff --git a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_target.c b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_target.c index 2de6d9f6877f0211aedf77892a064d944e29b6f8..95bb6be2d2d3441d932e212ad23a3d623c6bb554 100644 --- a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_target.c +++ b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_target.c @@ -6,20 +6,21 @@ #include __attribute__((target("sme"))) -void test_sme(svbool_t pg, void *ptr) { +void test_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svld1_hor_za8(0, 0, pg, ptr); } __attribute__((target("arch=armv8-a+sme"))) -void test_arch_sme(svbool_t pg, void *ptr) { +void test_arch_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svld1_hor_vnum_za32(0, 0, pg, ptr, 0); } __attribute__((target("+sme"))) -void test_plus_sme(svbool_t pg, void *ptr) { +void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za { svst1_ver_za16(0, 0, pg, ptr); } -void undefined(svbool_t pg, void *ptr) { - svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error {{'svst1_ver_vnum_za64' needs target feature sme}} +__attribute__((target("+sme"))) +void undefined(svbool_t pg, void *ptr) __arm_shared_za { + svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-warning {{builtin call has undefined behaviour when called from a non-streaming function}} } diff --git a/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp index 3750045fd8dff36c922688ef26d4157620b10e84..6a6370bf99b108f664796f2cab08605077b48792 100644 --- a/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp +++ b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp @@ -5,6 +5,57 @@ #include +void test_multivector_read(uint32_t base) __arm_streaming __arm_shared_za __arm_preserves_za { + + // Test Tile Range + svread_hor_za8_u8_vg2(1, base); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + svread_ver_za8_u8_vg2(1, base); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + svread_hor_za8_u8_vg4(1, base); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + svread_ver_za8_u8_vg4(1, base); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + + svread_hor_za16_u16_vg2(2, base); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svread_ver_za16_u16_vg2(2, base); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svread_hor_za16_u16_vg4(2, base); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svread_ver_za16_u16_vg4(2, base); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + + svread_hor_za32_u32_vg2(4, base); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svread_ver_za32_u32_vg2(4, base); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svread_hor_za32_u32_vg4(4, base); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svread_ver_za32_u32_vg4(4, base); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + + svread_hor_za64_u64_vg2(8, base); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svread_ver_za64_u64_vg2(8, base); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svread_hor_za64_u64_vg4(8, base); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svread_ver_za64_u64_vg4(8, base); // expected-error {{argument value 8 is outside the valid range [0, 7]}} +} + +void test_multivector_write(uint32_t base, svuint8x2_t v8x2, svuint8x4_t v8x4, + svuint16x2_t v16x2, svuint16x4_t v16x4, + svuint32x2_t v32x2, svuint32x4_t v32x4, + svuint64x2_t v64x2, svuint64x4_t v64x4) __arm_streaming __arm_shared_za { + + // Test Tile Range + svwrite_hor_za8_u8_vg2(1, base, v8x2); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + svwrite_ver_za8_u8_vg2(1, base, v8x2); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + svwrite_hor_za8_u8_vg4(1, base, v8x4); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + svwrite_ver_za8_u8_vg4(1, base, v8x4); // expected-error {{argument value 1 is outside the valid range [0, 0]}} + + svwrite_hor_za16_u16_vg2(2, base, v16x2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svwrite_ver_za16_u16_vg2(2, base, v16x2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svwrite_hor_za16_u16_vg4(2, base, v16x4); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svwrite_ver_za16_u16_vg4(2, base, v16x4); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + + svwrite_hor_za32_u32_vg2(4, base, v32x2); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svwrite_ver_za32_u32_vg2(4, base, v32x2); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svwrite_hor_za32_u32_vg4(4, base, v32x4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svwrite_ver_za32_u32_vg4(4, base, v32x4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + + svwrite_hor_za64_u64_vg2(8, base, v64x2); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svwrite_ver_za64_u64_vg2(8, base, v64x2); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svwrite_hor_za64_u64_vg4(8, base, v64x4); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svwrite_ver_za64_u64_vg4(8, base, v64x4); // expected-error {{argument value 8 is outside the valid range [0, 7]}} +} + void test_outer_product(svbool_t pred, svint16_t s16, svuint16_t u16, svint32_t s32, svuint32_t u32) __arm_streaming __arm_shared_za { // Test Tile Range svmopa_za32_u16_m(4, pred, pred, u16, u16); // expected-error {{argument value 4 is outside the valid range [0, 3]}} @@ -185,3 +236,117 @@ void test_svluti4_lane_zt_x2(svuint8_t zn_u8) __arm_streaming __arm_shared_za __ // Test index value range svluti4_lane_zt_f32_x2(0, zn_u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} } + +void test_bfmlslb_bad_lane(svfloat32_t zda, svbfloat16_t zn, svbfloat16_t zm) __arm_streaming_compatible { + svbfmlslb_lane_f32(zda, zn, zm, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svbfmlslt_lane_f32(zda, zn, zm, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} +} + +void test_multiply_add_sub_long(uint32_t base, svint8_t s8, svuint8_t u8, + svint16_t s16, svuint16_t u16, svint8x2_t s8x2, + svuint8x2_t u8x2, svint16x2_t s16x2, svuint16x2_t u16x2, + svint8x4_t s8x4, svuint8x4_t u8x4, svint16x4_t s16x4, svuint16x4_t u16x4) __arm_streaming __arm_shared_za { + + svmla_lane_za32_s8_vg4x1(base, s8, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za32_u8_vg4x1(base, u8, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za64_s16_vg4x1(base, s16, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svmla_lane_za64_u16_vg4x1(base, u16, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + + svmla_lane_za32_s8_vg4x2(base, s8x2, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za32_u8_vg4x2(base, u8x2, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za64_s16_vg4x2(base, s16x2, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svmla_lane_za64_u16_vg4x2(base, u16x2, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + + svmla_lane_za32_s8_vg4x4(base, s8x4, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za32_u8_vg4x4(base, u8x4, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za64_s16_vg4x4(base, s16x4, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svmla_lane_za64_u16_vg4x4(base, u16x4, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + + svmls_lane_za32_s8_vg4x1(base, s8, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmls_lane_za32_u8_vg4x1(base, u8, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmls_lane_za64_s16_vg4x1(base, s16, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svmls_lane_za64_u16_vg4x1(base, u16, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + + svmls_lane_za32_s8_vg4x2(base, s8x2, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmls_lane_za32_u8_vg4x2(base, u8x2, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmls_lane_za64_s16_vg4x2(base, s16x2, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svmls_lane_za64_u16_vg4x2(base, u16x2, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + + svmls_lane_za32_s8_vg4x4(base, s8x4, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmls_lane_za32_u8_vg4x4(base, u8x4, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svmls_lane_za64_s16_vg4x4(base, s16x4, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svmls_lane_za64_u16_vg4x4(base, u16x4, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + + svsumla_lane_za32_s8_vg4x1(base, s8, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svsumla_lane_za32_s8_vg4x2(base, s8x2, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svsumla_lane_za32_s8_vg4x4(base, s8x4, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + + svusmla_lane_za32_u8_vg4x1(base, u8, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svusmla_lane_za32_u8_vg4x2(base, u8x2, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svusmla_lane_za32_u8_vg4x4(base, u8x4, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} +} + +void test_vertical_dot_product(uint32_t base, svint16x2_t s16x2, svuint16x2_t u16x2, + svint8x4_t s8x4, svuint8x4_t u8x4, + svint16x4_t s16x4, svuint16x4_t u16x4, + svfloat16x2_t f16x2, svbfloat16x2_t bf16x2, + svint16_t s16, svuint16_t u16, + svint8_t s8, svuint8_t u8, + svfloat16_t f16, svbfloat16_t b16) __arm_streaming __arm_shared_za { + // Test lane indices. + svvdot_lane_za32_s16_vg1x2(base, s16x2, s16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svvdot_lane_za32_u16_vg1x2(base, u16x2, u16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svvdot_lane_za32_s8_vg1x4(base, s8x4, s8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svvdot_lane_za32_u8_vg1x4(base, u8x4, u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svvdot_lane_za64_s16_vg1x4(base, s16x4, s16, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svvdot_lane_za64_u16_vg1x4(base, u16x4, u16, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svvdot_lane_za32_f16_vg1x2(base, f16x2, f16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svvdot_lane_za32_bf16_vg1x2(base, bf16x2, b16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svsuvdot_lane_za32_s8_vg1x4(base, s8x4, s8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svusvdot_lane_za32_u8_vg1x4(base, u8x4, u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} +} + +void test_fdot_za32_bad_lane(uint32_t slice_base, svfloat16_t z_f16, + svfloat16x2_t z_f16x2, svfloat16x4_t z_f16x4, + svbfloat16_t z_bf16, svbfloat16x2_t z_bf16x2, + svbfloat16x4_t z_bf16x4) __arm_streaming __arm_shared_za { + // 16-bit float + svdot_lane_za32_f16_vg1x2(slice_base, z_f16x2, z_f16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_f16_vg1x4(slice_base, z_f16x4, z_f16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + + // 16-bit binary float + svdot_lane_za32_bf16_vg1x2(slice_base, z_bf16x2, z_bf16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_bf16_vg1x4(slice_base, z_bf16x4, z_bf16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} +} + +void test_svdot_multi_za32_bad_lane(uint32_t slice_base, svuint16_t z_u16, + svuint16x2_t z_u16x2, svuint16x4_t z_u16x4, + svint16_t z_s16, svint16x2_t z_s16x2, + svint16x4_t z_s16x4, svuint8_t z_u8, + svuint8x2_t z_u8x2, svuint8x4_t z_u8x4, + svint8_t z_s8, svint8x2_t z_s8x2, + svint8x4_t z_s8x4) __arm_streaming __arm_shared_za { + // Multi, indexed (unsigned) + svdot_lane_za32_u16_vg1x2(slice_base, z_u16x2, z_u16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_u16_vg1x4(slice_base, z_u16x4, z_u16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_u8_vg1x2(slice_base, z_u8x2, z_u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_u8_vg1x4(slice_base, z_u8x4, z_u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za64_u16_vg1x2(slice_base, z_u16x2, z_u16, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svdot_lane_za64_u16_vg1x4(slice_base, z_u16x4, z_u16, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + + // Multi, indexed (signed) + svdot_lane_za32_s16_vg1x2(slice_base, z_s16x2, z_s16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_s16_vg1x4(slice_base, z_s16x4, z_s16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_s8_vg1x2(slice_base, z_s8x2, z_s8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_s8_vg1x4(slice_base, z_s8x4, z_s8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za64_s16_vg1x2(slice_base, z_s16x2, z_s16, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svdot_lane_za64_s16_vg1x4(slice_base, z_s16x4, z_s16, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + + // Multi, indexed (unsigned by signed) + svusdot_lane_za32_u8_vg1x2(slice_base, z_u8x2, z_s8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svusdot_lane_za32_u8_vg1x4(slice_base, z_u8x4, z_s8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + + // Multi, indexed (unsigned by signed) + svsudot_lane_za32_s8_vg1x2(slice_base, z_s8x2, z_u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svsudot_lane_za32_s8_vg1x4(slice_base, z_s8x4, z_u8, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} +} diff --git a/clang/test/Sema/aarch64-sve-intrinsics/acle_sve_target.cpp b/clang/test/Sema/aarch64-sve-intrinsics/acle_sve_target.cpp index f41030c18e932bc68037046a87685fa9bdff0747..2f771ca170e76aab1b3fd8e5a42f299bf485567c 100644 --- a/clang/test/Sema/aarch64-sve-intrinsics/acle_sve_target.cpp +++ b/clang/test/Sema/aarch64-sve-intrinsics/acle_sve_target.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify -emit-llvm -o - -ferror-limit 100 %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -fsyntax-only -verify -emit-llvm -o - -ferror-limit 100 %s // REQUIRES: aarch64-registered-target // Test that functions with the correct target attributes can use the correct SVE intrinsics. @@ -29,4 +29,5 @@ void __attribute__((target("sve2-sha3"))) test_sve2_sha3() void __attribute__((target("sve2"))) test_f16(svbool_t pg) { svlogb_f16_z(pg, svundef_f16()); -} \ No newline at end of file +} + diff --git a/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp b/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp index f90ae0fb50e5fca0200dd5213b1516d14dda9c7c..a3ec4c5b8b1bc750edebf9806e74a2056e78992f 100644 --- a/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp +++ b/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple aarch14-none-linux-gnu -target-feature +sve2p1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -fsyntax-only -verify %s -// REQUIRES: aarch14-registered-target +// REQUIRES: aarch64-registered-target #include void test_svpext_lane_imm_0_3(svcount_t c) { @@ -27,7 +27,43 @@ void test_svpext_lane_x2_imm_0_1(svcount_t c) { svpext_lane_c64_x2(c, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} } -svcount_t test_svwhile_pn(int64_t op1, int64_t op2) { +svcount_t test_svwhile_pn_signed(int64_t op1, int64_t op2) { + svwhilege_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilege_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilege_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilege_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilegt_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilegt_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilegt_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilegt_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilele_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilele_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilele_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilele_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilelt_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilelt_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilelt_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + svwhilelt_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} + + svwhilege_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilege_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilege_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilege_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilegt_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilegt_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilegt_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilegt_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilele_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilele_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilele_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilele_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilelt_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilelt_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilelt_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} + svwhilelt_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} +} + +svcount_t test_svwhile_pn_unsigned(uint64_t op1, uint64_t op2) { svwhilege_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilege_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilege_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} @@ -36,26 +72,10 @@ svcount_t test_svwhile_pn(int64_t op1, int64_t op2) { svwhilegt_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilegt_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilegt_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehi_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehi_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehi_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehi_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehs_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehs_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehs_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilehs_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilele_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilele_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilele_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilele_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilelo_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilelo_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilelo_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilelo_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilels_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilels_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilels_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} - svwhilels_c64(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilelt_c8(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilelt_c16(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} svwhilelt_c32(op1, op2, 6); // expected-error {{argument value 6 is outside the valid range [2, 4]}} @@ -69,26 +89,10 @@ svcount_t test_svwhile_pn(int64_t op1, int64_t op2) { svwhilegt_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilegt_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilegt_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehi_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehi_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehi_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehi_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehs_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehs_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehs_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilehs_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilele_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilele_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilele_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilele_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilelo_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilelo_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilelo_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilelo_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilels_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilels_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilels_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} - svwhilels_c64(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilelt_c8(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilelt_c16(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} svwhilelt_c32(op1, op2, 3); // expected-error {{argument should be a multiple of 2}} @@ -97,21 +101,19 @@ svcount_t test_svwhile_pn(int64_t op1, int64_t op2) { void test_cntp(svcount_t c) { svcntp_c8(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}} - svcntp_c11(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}} + svcntp_c16(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}} svcntp_c32(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}} - svcntp_c14(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}} + svcntp_c64(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}} svcntp_c8(c, 3); // expected-error {{argument should be a multiple of 2}} - svcntp_c11(c, 3); // expected-error {{argument should be a multiple of 2}} + svcntp_c16(c, 3); // expected-error {{argument should be a multiple of 2}} svcntp_c32(c, 3); // expected-error {{argument should be a multiple of 2}} - svcntp_c14(c, 3); // expected-error {{argument should be a multiple of 2}} + svcntp_c64(c, 3); // expected-error {{argument should be a multiple of 2}} } + void test_svdot_lane_2way(svint32_t s32, svuint32_t u32, svint16_t s16, svuint16_t u16, svfloat32_t f32, svfloat16_t f16) { - svdot_lane_s32_s16_s16(s32, s16, s16, 1); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - svdot_lane_u32_u16_u16(u32, u16, u16, 1); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - svdot_lane_f32_f16_f16(f32, f16, f16, 1); // expected-error {{argument value 4 is outside the valid range [0, 3]}} svdot_lane_s32_s16_s16(s32, s16, s16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} svdot_lane_u32_u16_u16(u32, u16, u16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} svdot_lane_f32_f16_f16(f32, f16, f16, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} @@ -124,8 +126,8 @@ void test_svbfml_lane(svbfloat16_t zda, svbfloat16_t zn, svbfloat16_t zm, uint64 svmla_lane_bf16(zda, zn, zm, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} svmls_lane_bf16(zda, zn, zm, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 7]}} svmls_lane_bf16(zda, zn, zm, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} - svmla_lane_bf16(zda, zn, zm, idx); // expected-errcor {{argument to 'svmla_lane_bf16' must be a constant integer}} - svmls_lane_bf16(zda, zn, zm, idx); // expected-error {{argument to 'svmla_lane_bf16' must be a constant integer}} + svmla_lane_bf16(zda, zn, zm, idx); // expected-error {{argument to 'svmla_lane_bf16' must be a constant integer}} + svmls_lane_bf16(zda, zn, zm, idx); // expected-error {{argument to 'svmls_lane_bf16' must be a constant integer}} } __attribute__((target("+sve2p1+b16b16"))) @@ -133,6 +135,7 @@ void test_svbfmul_lane(svbfloat16_t zn, svbfloat16_t zm, uint64_t idx){ svmul_lane_bf16(zn, zm, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 7]}} svmul_lane_bf16(zn, zm, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} svmul_lane_bf16(zn, zm, idx); // expected-error {{argument to 'svmul_lane_bf16' must be a constant integer}} +} __attribute__((target("+sve2p1"))) void test_svextq_lane(svint16_t zn_i16, svint16_t zm_i16, svfloat16_t zn_f16, svfloat16_t zm_f16){ @@ -148,10 +151,10 @@ void test_svpmov_lane(){ svuint64_t zn_u64; svbool_t pn; - svpmov_lane_u8(zn_u8, -1); // expected-error {{argument value -1 is outside the valid range [0, 0]}} - svpmov_lane_u16(zn_u16, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} - svpmov_lane_u32(zn_u32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} - svpmov_lane_u64(zn_u64, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + svpmov_lane_u8(zn_u8, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 0]}} + svpmov_lane_u16(zn_u16, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 1]}} + svpmov_lane_u32(zn_u32, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svpmov_lane_u64(zn_u64, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 7]}} svpmov_lane_u8(zn_u8, 1); // expected-error {{argument value 1 is outside the valid range [0, 0]}} svpmov_lane_u16(zn_u16, 3); // expected-error {{argument value 3 is outside the valid range [0, 1]}} @@ -180,8 +183,8 @@ void test_svget_svset_b(uint64_t idx, svboolx2_t tuple2, svboolx4_t tuple4, svbo svget4(tuple4, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}} svget4(tuple4, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} - svset2(tuple2, idx, res); // expected-error {{argument to 'svste2' must be a constant integer}} - svset4(tupl4, idx, res); // expected-error {{argument to 'svset4' must be a constant integer}} + svset2(tuple2, idx, res); // expected-error {{argument to 'svset2' must be a constant integer}} + svset4(tuple4, idx, res); // expected-error {{argument to 'svset4' must be a constant integer}} svget2(tuple2, idx); // expected-error {{argument to 'svget2' must be a constant integer}} svget4(tuple4, idx); // expected-error {{argument to 'svget4' must be a constant integer}} } diff --git a/clang/test/Sema/arm-vector-types-support.c b/clang/test/Sema/arm-vector-types-support.c index fa101afa3122adee457589f8165b0192b3bbd827..83a83ddfe780170cde85da81058b22d425ced113 100644 --- a/clang/test/Sema/arm-vector-types-support.c +++ b/clang/test/Sema/arm-vector-types-support.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -triple armv7 -fsyntax-only -verify -typedef __attribute__((neon_vector_type(2))) int int32x2_t; // expected-error{{'neon_vector_type' attribute is not supported on targets missing 'neon' or 'mve'; specify an appropriate -march= or -mcpu=}} +typedef __attribute__((neon_vector_type(2))) int int32x2_t; // expected-error{{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'; specify an appropriate -march= or -mcpu=}} typedef __attribute__((neon_polyvector_type(16))) short poly8x16_t; // expected-error{{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'; specify an appropriate -march= or -mcpu=}} typedef __attribute__((arm_sve_vector_bits(256))) void nosveflag; // expected-error{{'arm_sve_vector_bits' attribute is not supported on targets missing 'sve'; specify an appropriate -march= or -mcpu=}} diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c index 4fa1223b3038f3171b4c8b97935c71e24f576bdc..1d36667d6cf40995821e0f303ae6b3b1864da053 100644 --- a/clang/test/Sema/atomic-ops.c +++ b/clang/test/Sema/atomic-ops.c @@ -339,18 +339,18 @@ void memory_checks(_Atomic(int) *Ap, int *p, int val) { (void)__c11_atomic_load(Ap, memory_order_relaxed); (void)__c11_atomic_load(Ap, memory_order_acquire); (void)__c11_atomic_load(Ap, memory_order_consume); - (void)__c11_atomic_load(Ap, memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}} - (void)__c11_atomic_load(Ap, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} + (void)__c11_atomic_load(Ap, memory_order_release); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} + (void)__c11_atomic_load(Ap, memory_order_acq_rel); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} (void)__c11_atomic_load(Ap, memory_order_seq_cst); (void)__c11_atomic_load(Ap, val); - (void)__c11_atomic_load(Ap, -1); // expected-warning {{memory order argument to atomic operation is invalid}} - (void)__c11_atomic_load(Ap, 42); // expected-warning {{memory order argument to atomic operation is invalid}} + (void)__c11_atomic_load(Ap, -1); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} + (void)__c11_atomic_load(Ap, 42); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} (void)__c11_atomic_store(Ap, val, memory_order_relaxed); - (void)__c11_atomic_store(Ap, val, memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}} - (void)__c11_atomic_store(Ap, val, memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}} + (void)__c11_atomic_store(Ap, val, memory_order_acquire); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} + (void)__c11_atomic_store(Ap, val, memory_order_consume); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} (void)__c11_atomic_store(Ap, val, memory_order_release); - (void)__c11_atomic_store(Ap, val, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} + (void)__c11_atomic_store(Ap, val, memory_order_acq_rel); // expected-warning-re {{{{^}}memory order argument to atomic operation is invalid}} (void)__c11_atomic_store(Ap, val, memory_order_seq_cst); (void)__c11_atomic_fetch_add(Ap, 1, memory_order_relaxed); @@ -427,19 +427,35 @@ void memory_checks(_Atomic(int) *Ap, int *p, int val) { (void)__c11_atomic_exchange(Ap, val, memory_order_acq_rel); (void)__c11_atomic_exchange(Ap, val, memory_order_seq_cst); + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, -1, memory_order_relaxed); // expected-warning {{success memory order argument to atomic operation is invalid}} (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_relaxed, memory_order_relaxed); (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_acquire, memory_order_relaxed); (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_consume, memory_order_relaxed); (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_release, memory_order_relaxed); (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_acq_rel, memory_order_relaxed); - (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_relaxed); - + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_acquire); + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_consume); + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_release); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_acq_rel); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_seq_cst); + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, -1); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_relaxed, memory_order_acquire); + (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_acquire, memory_order_seq_cst); + + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, -1, memory_order_relaxed); // expected-warning {{success memory order argument to atomic operation is invalid}} (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_relaxed, memory_order_relaxed); (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_acquire, memory_order_relaxed); (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_consume, memory_order_relaxed); (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_release, memory_order_relaxed); (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_acq_rel, memory_order_relaxed); - (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_relaxed); + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_acquire); + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_consume); + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_release); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_acq_rel); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_seq_cst); + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, -1); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_relaxed, memory_order_acquire); + (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_acquire, memory_order_seq_cst); (void)__atomic_load_n(p, memory_order_relaxed); (void)__atomic_load_n(p, memory_order_acquire); @@ -595,19 +611,32 @@ void memory_checks(_Atomic(int) *Ap, int *p, int val) { (void)__atomic_exchange(p, p, p, memory_order_acq_rel); (void)__atomic_exchange(p, p, p, memory_order_seq_cst); + (void)__atomic_compare_exchange(p, p, p, 0, -1, memory_order_relaxed); // expected-warning {{success memory order argument to atomic operation is invalid}} (void)__atomic_compare_exchange(p, p, p, 0, memory_order_relaxed, memory_order_relaxed); (void)__atomic_compare_exchange(p, p, p, 0, memory_order_acquire, memory_order_relaxed); (void)__atomic_compare_exchange(p, p, p, 0, memory_order_consume, memory_order_relaxed); (void)__atomic_compare_exchange(p, p, p, 0, memory_order_release, memory_order_relaxed); (void)__atomic_compare_exchange(p, p, p, 0, memory_order_acq_rel, memory_order_relaxed); - (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_relaxed); - + (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_acquire); + (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_consume); + (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_release); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_acq_rel); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_seq_cst); + (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, -1); // expected-warning {{memory order argument to atomic operation is invalid}} + + (void)__atomic_compare_exchange_n(p, p, val, 0, -1, memory_order_relaxed); // expected-warning {{success memory order argument to atomic operation is invalid}} (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_relaxed, memory_order_relaxed); (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_acquire, memory_order_relaxed); (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_consume, memory_order_relaxed); (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_release, memory_order_relaxed); (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_acq_rel, memory_order_relaxed); (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_relaxed); + (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_acquire); + (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_consume); + (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_release); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_acq_rel); // expected-warning {{failure memory order argument to atomic operation is invalid}} + (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_seq_cst); + (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, -1); // expected-warning {{memory order argument to atomic operation is invalid}} } void nullPointerWarning(void) { diff --git a/clang/test/Sema/attr-counted-by.c b/clang/test/Sema/attr-counted-by.c deleted file mode 100644 index ab3b6e6d710b50373b313c7bccd8ebf5b037c651..0000000000000000000000000000000000000000 --- a/clang/test/Sema/attr-counted-by.c +++ /dev/null @@ -1,55 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#define __counted_by(f) __attribute__((counted_by(f))) - -struct bar; - -struct not_found { - int count; - struct bar *fam[] __counted_by(bork); // expected-error {{use of undeclared identifier 'bork'}} -}; - -struct not_found_suggest { - int bork; // expected-note {{'bork' declared here}} - struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'; did you mean 'bork'?}} -}; - -int global; // expected-note {{'global' declared here}} - -struct found_outside_of_struct { - int bork; - struct bar *fam[] __counted_by(global); // expected-error {{field 'global' in 'counted_by' not inside structure}} -}; - -struct self_referrential { - int bork; - struct bar *self[] __counted_by(self); // expected-error {{'counted_by' cannot refer to the flexible array 'self'}} -}; - -struct non_int_count { - double dbl_count; // expected-note {{field 'dbl_count' declared here}} - struct bar *fam[] __counted_by(dbl_count); // expected-error {{field 'dbl_count' in 'counted_by' must be a non-boolean integer type}} -}; - -struct array_of_ints_count { - int integers[2]; // expected-note {{field 'integers' declared here}} - struct bar *fam[] __counted_by(integers); // expected-error {{field 'integers' in 'counted_by' must be a non-boolean integer type}} -}; - -struct not_a_fam { - int count; - struct bar *non_fam __counted_by(count); // expected-error {{'counted_by' only applies to C99 flexible array members}} -}; - -struct not_a_c99_fam { - int count; - struct bar *non_c99_fam[0] __counted_by(count); // expected-error {{'counted_by' only applies to C99 flexible array members}} -}; - -struct annotated_with_anon_struct { - unsigned long flags; - struct { - unsigned char count; // expected-note {{'count' declared here}} - int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'; did you mean 'count'?}} - }; -}; diff --git a/clang/test/Sema/no_stack_protector.c b/clang/test/Sema/no_stack_protector.c index 0007435901e8405689ba2a6262e67ba00b942885..1ecd46bc624ceb14dbda75549ef28d0dcbe88d4d 100644 --- a/clang/test/Sema/no_stack_protector.c +++ b/clang/test/Sema/no_stack_protector.c @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s + +[[gnu::no_stack_protector]] void test1(void) {} +[[clang::no_stack_protector]] void test2(void) {} void __attribute__((no_stack_protector)) foo(void) {} int __attribute__((no_stack_protector)) var; // expected-warning {{'no_stack_protector' attribute only applies to functions}} diff --git a/clang/test/Sema/no_stack_protector.cpp b/clang/test/Sema/no_stack_protector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..160e3d32a9389a782da8c7a0f9b769ba44211306 --- /dev/null +++ b/clang/test/Sema/no_stack_protector.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// expected-no-diagnostics + +[[gnu::no_stack_protector]] void test1() {} +[[clang::no_stack_protector]] void test2() {} diff --git a/clang/test/Sema/riscv-vector-zve32x-check.c b/clang/test/Sema/riscv-vector-zve32x-check.c index a021de8bf31fb4acb05eccfdca0d2f2c09feddf4..aff6e477378c46ca35a66c474fc6caafb7f405a4 100644 --- a/clang/test/Sema/riscv-vector-zve32x-check.c +++ b/clang/test/Sema/riscv-vector-zve32x-check.c @@ -97,11 +97,3 @@ __rvv_bool32_t vbool32 () { /* expected-error {{RISC-V type '__rvv_bool32_t' req return b32; /* expected-error {{RISC-V type '__rvv_bool32_t' requires the 'zve32x' extension}} */ } - -__rvv_bool64_t vbool64 () { /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve32x' extension}} */ - __rvv_bool64_t b64; /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve32x' extension}} */ - - (void)b64; /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve32x' extension}} */ - - return b64; /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve32x' extension}} */ -} diff --git a/clang/test/Sema/riscv-vector-zve64x-check.c b/clang/test/Sema/riscv-vector-zve64x-check.c index 5fb2ad483f63f21e9bed513e2e29ec2b495d7251..7ef156832702d5942eb3675252b001af1d22dd1b 100644 --- a/clang/test/Sema/riscv-vector-zve64x-check.c +++ b/clang/test/Sema/riscv-vector-zve64x-check.c @@ -37,3 +37,11 @@ __rvv_int64m1_t foo64() { /* expected-error {{RISC-V type '__rvv_int64m1_t' requ return i64m1; /* expected-error {{RISC-V type '__rvv_int64m1_t' requires the 'zve64x' extension}} */ } + +__rvv_bool64_t vbool64 () { /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve64x' extension}} */ + __rvv_bool64_t b64; /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve64x' extension}} */ + + (void)b64; /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve64x' extension}} */ + + return b64; /* expected-error {{RISC-V type '__rvv_bool64_t' requires the 'zve64x' extension}} */ +} diff --git a/clang/test/Sema/rvv-required-features.c b/clang/test/Sema/rvv-required-features.c index 2714ef04b9bf226fd306dd7c1c060b4423ab712e..5846f338aa80105044464d8a8f9bb2e7eb87c180 100644 --- a/clang/test/Sema/rvv-required-features.c +++ b/clang/test/Sema/rvv-required-features.c @@ -1,8 +1,6 @@ // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp \ -// RUN: -target-feature +xsfvqmaccdod -target-feature +xsfvqmaccqoq \ -// RUN: -target-feature +experimental-zvfbfmin -target-feature +xsfvfwmaccqqq \ -// RUN: -target-feature +xsfvfnrclipxfqf %s -fsyntax-only -verify +// RUN: -target-feature +xsfvqmaccdod -target-feature +xsfvqmaccqoq %s -fsyntax-only -verify // expected-no-diagnostics @@ -25,18 +23,6 @@ void test_xsfvqmaccdod(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { __riscv_sf_vqmacc_2x8x2(vd, vs1, vs2, vl); } -void test_xsfvqmaccqoq(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { +void test_xsfvqmaccqoq(vint32m1_t vd, vint8m1_t vs1, vint8mf2_t vs2, size_t vl) { __riscv_sf_vqmacc_4x8x4(vd, vs1, vs2, vl); } - -void test_xsfvfwmaccqqq(vfloat32m1_t vd, vbfloat16m1_t vs1, vbfloat16mf2_t vs2, size_t vl) { - __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); -} - -void test_xsfvfnrclipxufqf(vfloat32m1_t vs1, float rs2, size_t vl) { - __riscv_sf_vfnrclip_xu_f_qf(vs1, rs2, vl); -} - -void test_xsfvfnrclipxfqf(vfloat32m1_t vs1, float rs2, size_t vl) { - __riscv_sf_vfnrclip_x_f_qf(vs1, rs2, vl); -} diff --git a/clang/test/Sema/switch-default.c b/clang/test/Sema/switch-default.c deleted file mode 100644 index 854b561b37c48e4e2d12ec7737a8509fa742ba19..0000000000000000000000000000000000000000 --- a/clang/test/Sema/switch-default.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-default %s - -int f1(int a) { - switch (a) { // expected-warning {{'switch' missing 'default' label}} - case 1: a++; break; - case 2: a += 2; break; - } - return a; -} - -int f2(int a) { - switch (a) { // no-warning - default: - ; - } - return a; -} diff --git a/clang/test/Sema/switch-default.cpp b/clang/test/Sema/switch-default.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32d03dae882733426613cbb71dd021e9079a726a --- /dev/null +++ b/clang/test/Sema/switch-default.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wswitch-default %s + +int f1(int a) { + switch (a) { // expected-warning {{'switch' missing 'default' label}} + case 1: a++; break; + case 2: a += 2; break; + } + return a; +} + +int f2(int a) { + switch (a) { // no-warning + default: + ; + } + return a; +} + +// Warn even completely covered Enum cases(GCC compatibility). +enum E { A, B }; +enum E check_enum(enum E e) { + switch (e) { // expected-warning {{'switch' missing 'default' label}} + case A: break; + case B: break; + } + return e; +} + +template +int t1(Index i) +{ + switch (i) { // expected-warning {{'switch' missing 'default' label}} + case 0: return 0; + case 1: return 1; + } + return 0; +} + +template +int t2(Index i) +{ + switch (i) { // no-warning + case 0: return 0; + case 1: return 1; + default: return 2; + } + return 0; +} + +int main() { + return t1(1); // expected-note {{in instantiation of function template specialization 't1' requested here}} +} + diff --git a/clang/test/Sema/zvk-invalid-vlen.c b/clang/test/Sema/zvk-invalid-vlen.c index a737d620e7aa6eed796ef3596a9dc3f8f8935d0f..725c126f28908d89e1c150079d3f5d457b8bf5f1 100644 --- a/clang/test/Sema/zvk-invalid-vlen.c +++ b/clang/test/Sema/zvk-invalid-vlen.c @@ -1,6 +1,6 @@ // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvkned \ -// RUN: -target-feature +experimental-zvksh %s -fsyntax-only -verify +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvkned \ +// RUN: -target-feature +zvksh -target-feature +experimental %s -fsyntax-only -verify #include diff --git a/clang/test/Sema/zvk-invalid-zvknha.c b/clang/test/Sema/zvk-invalid-zvknha.c index 0ce2e321a175f5f4a70676d1d639141d5aa62a6c..a0a4cf8fb86d5e24bd0ed06f4a6ff9392f6ca53e 100644 --- a/clang/test/Sema/zvk-invalid-zvknha.c +++ b/clang/test/Sema/zvk-invalid-zvknha.c @@ -1,5 +1,5 @@ // REQUIRES: riscv-registered-target -// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +experimental-zvknha %s -fsyntax-only -verify +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvknha %s -fsyntax-only -verify #include diff --git a/clang/test/SemaCUDA/atomic-ops.cu b/clang/test/SemaCUDA/atomic-ops.cu index af93b7e1e79448bc8739f5308bce5bdc94b99732..233ed1c10fc1132d84836d855f688855b5a4d3ff 100644 --- a/clang/test/SemaCUDA/atomic-ops.cu +++ b/clang/test/SemaCUDA/atomic-ops.cu @@ -76,7 +76,7 @@ __device__ bool test_hip_atomic_cmpxchg_weak(int *ptr, int val, int desired) { flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST, __HIP_MEMORY_SCOPE_SINGLETHREAD); flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_CONSUME, __HIP_MEMORY_SCOPE_SINGLETHREAD); flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SINGLETHREAD); - flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_ACQ_REL, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_ACQ_REL, __HIP_MEMORY_SCOPE_SINGLETHREAD); // expected-warning {{failure memory order argument to atomic operation is invalid}} flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_CONSUME, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); diff --git a/clang/test/SemaCUDA/neon-attrs.cu b/clang/test/SemaCUDA/neon-attrs.cu index a72b03f3bbbd7e31dc9777c78db46d92546ba625..129056741ac9a46ae7811768369a45f0c7166829 100644 --- a/clang/test/SemaCUDA/neon-attrs.cu +++ b/clang/test/SemaCUDA/neon-attrs.cu @@ -15,7 +15,8 @@ // quiet-no-diagnostics typedef __attribute__((neon_vector_type(4))) float float32x4_t; -// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon' or 'mve'}} +// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'}} +// expect typedef unsigned char poly8_t; typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t; // expected-error@-1 {{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'}} diff --git a/clang/test/SemaCXX/GH63151.cpp b/clang/test/SemaCXX/GH63151.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4d0da0beee217e4e45e2b1a13e70e5fb1a92f72 --- /dev/null +++ b/clang/test/SemaCXX/GH63151.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=expected,narrowing %s +// RUN: %clang_cc1 -fsyntax-only -Wno-c++11-narrowing-const-reference -verify %s + +struct A { A(const unsigned &x) {} }; + +void foo(int p) { + A a { -1 }; // narrowing-error {{constant expression evaluates to -1 which cannot be narrowed to type 'unsigned int'}} + A b { 0 }; + A c { p }; // narrowing-error {{non-constant-expression cannot be narrowed from type 'int' to 'unsigned int' in initializer list}} + A d { 0.5 }; // narrowing-error {{type 'double' cannot be narrowed to 'unsigned int' in initializer list}} + // expected-warning@-1 {{implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0}} +} diff --git a/clang/test/SemaCXX/attr-suppress.cpp b/clang/test/SemaCXX/attr-suppress.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb5e2ac7ce20667aa7aa57176f49d7ef9c70c4d5 --- /dev/null +++ b/clang/test/SemaCXX/attr-suppress.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify + +[[gsl::suppress("globally")]]; + +namespace N { +[[gsl::suppress("in-a-namespace")]]; +} + +[[gsl::suppress("readability-identifier-naming")]] void f_() { + int *p; + [[gsl::suppress("type", "bounds")]] { + p = reinterpret_cast(7); + } + + [[gsl::suppress]] int x; // expected-error {{'suppress' attribute takes at least 1 argument}} + [[gsl::suppress()]] int y; // expected-error {{'suppress' attribute takes at least 1 argument}} + int [[gsl::suppress("r")]] z; // expected-error {{'suppress' attribute cannot be applied to types}} + [[gsl::suppress(f_)]] float f; // expected-error {{expected string literal as argument of 'suppress' attribute}} +} + +union [[gsl::suppress("type.1")]] U { + int i; + float f; +}; + +[[clang::suppress]]; +// expected-error@-1 {{'suppress' attribute only applies to variables and statements}} + +namespace N { +[[clang::suppress("in-a-namespace")]]; +// expected-error@-1 {{'suppress' attribute only applies to variables and statements}} +} // namespace N + +[[clang::suppress]] int global = 42; + +[[clang::suppress]] void foo() { + // expected-error@-1 {{'suppress' attribute only applies to variables and statements}} + [[clang::suppress]] int *p; + + [[clang::suppress]] int a = 0; // no-warning + [[clang::suppress()]] int b = 1; // no-warning + [[clang::suppress("a")]] int c = a + b; // no-warning + [[clang::suppress("a", "b")]] b = c - a; // no-warning + + [[clang::suppress("a", "b")]] if (b == 10) a += 4; // no-warning + [[clang::suppress]] while (true) {} // no-warning + [[clang::suppress]] switch (a) { // no-warning + default: + c -= 10; + } + + int [[clang::suppress("r")]] z; + // expected-error@-1 {{'suppress' attribute cannot be applied to types}} + [[clang::suppress(foo)]] float f; + // expected-error@-1 {{expected string literal as argument of 'suppress' attribute}} +} + +class [[clang::suppress("type.1")]] V { + // expected-error@-1 {{'suppress' attribute only applies to variables and statements}} + int i; + float f; +}; diff --git a/clang/test/SemaCXX/crash-GH76228.cpp b/clang/test/SemaCXX/crash-GH76228.cpp new file mode 100644 index 0000000000000000000000000000000000000000..33a9395823127ea4aae006e055d1ed76bf52aad6 --- /dev/null +++ b/clang/test/SemaCXX/crash-GH76228.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s +// Check we don't crash on incomplete members and bases when handling parenthesized initialization. +class incomplete; // expected-note@-0 3 {{forward declaration of 'incomplete'}} +struct foo { + int a; + incomplete b; + // expected-error@-1 {{incomplete type}} +}; +foo a1(0); + +struct one_int { + int a; +}; +struct bar : one_int, incomplete {}; +// expected-error@-1 {{incomplete type}} +bar a2(0); + +incomplete a3[3](1,2,3); +// expected-error@-1 {{incomplete type}} + +struct qux : foo { +}; +qux a4(0); + +struct fred { + foo a[3]; +}; +fred a5(0); diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10806f107b4ee9d5b431a7295c68722017eb8364 --- /dev/null +++ b/clang/test/SemaCXX/ctad.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s +// expected-no-diagnostics + +namespace GH64347 { + +template struct A { X x; Y y;}; +void test() { + A(1, 2); + new A(1, 2); +} + +template +void f() { (void)a; } +void k() { + // Test CTAD works for non-type template arguments. + f(); +} + +} // namespace GH64347 diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 0033541fa322dc4f9e0089f2b5577931c3700373..aab35828096a8ef02ad43fbcf3b3199146534b73 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -626,3 +626,13 @@ void test() { } } + + +namespace GH75732 { +auto serialize(auto&& archive, auto&& c){ } +struct D { + auto serialize(this auto&& self, auto&& archive) { + serialize(archive, self); // expected-error {{call to explicit member function without an object argument}} + } +}; +} diff --git a/clang/test/SemaCXX/externc-ifunc-resolver.cpp b/clang/test/SemaCXX/externc-ifunc-resolver.cpp index aa44525bde2cae19088f83aa1cd7b3b0791a7e3c..6c6c262c5f09d8eebb8d10025f4fe1aa05da28bb 100644 --- a/clang/test/SemaCXX/externc-ifunc-resolver.cpp +++ b/clang/test/SemaCXX/externc-ifunc-resolver.cpp @@ -1,5 +1,9 @@ // RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-macosx -verify %s +// RUN: %clang_cc1 -emit-llvm-only -triple arm64-apple-macosx -verify %s // RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -triple x86_64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -triple arm64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s extern "C" { __attribute__((used)) static void *resolve_foo() { return 0; } diff --git a/clang/test/SemaCXX/ifunc-has-attribute.cpp b/clang/test/SemaCXX/ifunc-has-attribute.cpp new file mode 100644 index 0000000000000000000000000000000000000000..242f3b621745f59136a419dfe9d863f280aa7012 --- /dev/null +++ b/clang/test/SemaCXX/ifunc-has-attribute.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s -DSUPPORTED=1 +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-macosx -verify %s -DSUPPORTED=1 +// RUN: %clang_cc1 -emit-llvm-only -triple arm64-apple-macosx -verify %s -DSUPPORTED=1 +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-win32 -verify %s -DNOT_SUPPORTED=1 + +// expected-no-diagnostics + +#if __has_attribute(ifunc) +# if NOT_SUPPORTED +# error "ifunc appears to be supported on this platform, but shouldn't be" +# endif +#else +# if SUPPORTED +# error "ifunc should be supported on this platform, but isn't" +# endif +#endif diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp index f60b20e0d4656850c39e890f5dc21ea7a96a6799..c1964a5a9eb005817632994d668668923e7c15e5 100644 --- a/clang/test/SemaCXX/paren-list-agg-init.cpp +++ b/clang/test/SemaCXX/paren-list-agg-init.cpp @@ -289,7 +289,7 @@ int test() { // used to crash S a(0, 1); S b(0); - S c(0, 0, 1); // beforecxx20-warning {{aggregate initialization of type 'S' from a parenthesized list of values is a C++20 extension}} + S c(0, 0, 1); S d {0, 1}; S e {0}; diff --git a/clang/test/SemaCXX/suppress.cpp b/clang/test/SemaCXX/suppress.cpp deleted file mode 100644 index 29544b3c573ccc8695589605675ad1f54d33a75b..0000000000000000000000000000000000000000 --- a/clang/test/SemaCXX/suppress.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify - -[[gsl::suppress("globally")]]; - -namespace N { - [[gsl::suppress("in-a-namespace")]]; -} - -[[gsl::suppress("readability-identifier-naming")]] -void f_() { - int *p; - [[gsl::suppress("type", "bounds")]] { - p = reinterpret_cast(7); - } - - [[gsl::suppress]] int x; // expected-error {{'suppress' attribute takes at least 1 argument}} - [[gsl::suppress()]] int y; // expected-error {{'suppress' attribute takes at least 1 argument}} - int [[gsl::suppress("r")]] z; // expected-error {{'suppress' attribute cannot be applied to types}} - [[gsl::suppress(f_)]] float f; // expected-error {{expected string literal as argument of 'suppress' attribut}} -} - -union [[gsl::suppress("type.1")]] U { - int i; - float f; -}; diff --git a/clang/test/SemaObjC/Inputs/module.map b/clang/test/SemaObjC/Inputs/module.modulemap similarity index 100% rename from clang/test/SemaObjC/Inputs/module.map rename to clang/test/SemaObjC/Inputs/module.modulemap diff --git a/clang/test/SemaObjC/attr-suppress.m b/clang/test/SemaObjC/attr-suppress.m new file mode 100644 index 0000000000000000000000000000000000000000..ade8f94ec5895ef6d4f7a86780408be98527737b --- /dev/null +++ b/clang/test/SemaObjC/attr-suppress.m @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks %s -verify + +#define SUPPRESS1 __attribute__((suppress)) +#define SUPPRESS2(...) __attribute__((suppress(__VA_ARGS__))) + +SUPPRESS1 int global = 42; + +SUPPRESS1 void foo() { + // expected-error@-1 {{'suppress' attribute only applies to variables and statements}} + SUPPRESS1 int *p; + + SUPPRESS1 int a = 0; // no-warning + SUPPRESS2() + int b = 1; // no-warning + SUPPRESS2("a") + int c = a + b; // no-warning + SUPPRESS2("a", "b") { b = c - a; } // no-warning + + SUPPRESS2("a", "b") + if (b == 10) + a += 4; // no-warning + SUPPRESS1 while (1) {} // no-warning + SUPPRESS1 switch (a) { // no-warning + default: + c -= 10; + } + + // GNU-style attributes and C++11 attributes apply to different things when + // written like this. GNU attribute gets attached to the declaration, while + // C++11 attribute ends up on the type. + int SUPPRESS2("r") z; + SUPPRESS2(foo) + float f; + // expected-error@-2 {{expected string literal as argument of 'suppress' attribute}} +} + +union SUPPRESS2("type.1") U { + // expected-error@-1 {{'suppress' attribute only applies to variables and statements}} + int i; + float f; +}; + +SUPPRESS1 @interface Test { + // expected-error@-1 {{'suppress' attribute only applies to variables and statements}} +} +@property SUPPRESS2("prop") int *prop; +// expected-error@-1 {{'suppress' attribute only applies to variables and statements}} +- (void)bar:(int)x SUPPRESS1; +// expected-error@-1 {{'suppress' attribute only applies to variables and statements}} +@end diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx12-param.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx12-param.cl new file mode 100644 index 0000000000000000000000000000000000000000..0e0ea3646a2f1a9ff389f7c817c56c7cc41550fe --- /dev/null +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx12-param.cl @@ -0,0 +1,14 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx1200 -verify -S -o - %s + +typedef unsigned int uint; + +void test_permlane16_var(global uint* out, uint a, uint b, uint c, uint d) { + *out = __builtin_amdgcn_permlane16_var(a, b, c, d, 1); // expected-error{{argument to '__builtin_amdgcn_permlane16_var' must be a constant integer}} + *out = __builtin_amdgcn_permlane16_var(a, b, c, 1, d); // expected-error{{argument to '__builtin_amdgcn_permlane16_var' must be a constant integer}} +} + +void test_permlanex16_var(global uint* out, uint a, uint b, uint c, uint d) { + *out = __builtin_amdgcn_permlanex16_var(a, b, c, d, 1); // expected-error{{argument to '__builtin_amdgcn_permlanex16_var' must be a constant integer}} + *out = __builtin_amdgcn_permlanex16_var(a, b, c, 1, d); // expected-error{{argument to '__builtin_amdgcn_permlanex16_var' must be a constant integer}} +} diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx12.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx12.cl new file mode 100644 index 0000000000000000000000000000000000000000..34887a65021c33cc811ba095b5f634531be3b7a3 --- /dev/null +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx12.cl @@ -0,0 +1,16 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu tahiti -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu hawaii -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu fiji -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx900 -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx908 -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx1010 -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx1030 -verify -S -o - %s +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx1100 -verify -S -o - %s + +typedef unsigned int uint; + +void test(global uint* out, uint a, uint b, uint c) { + *out = __builtin_amdgcn_permlane16_var(a, b, c, 1, 1); // expected-error {{'__builtin_amdgcn_permlane16_var' needs target feature gfx12-insts}} + *out = __builtin_amdgcn_permlanex16_var(a, b, c, 1, 1); // expected-error {{'__builtin_amdgcn_permlanex16_var' needs target feature gfx12-insts}} +} diff --git a/clang/test/SemaTemplate/ctad.cpp b/clang/test/SemaTemplate/ctad.cpp index 4d836839d8c34622ae5df68003c3002ec77df2e9..388ed7d4cced18fb1a698d20983335d18481253b 100644 --- a/clang/test/SemaTemplate/ctad.cpp +++ b/clang/test/SemaTemplate/ctad.cpp @@ -44,3 +44,13 @@ namespace Access { }; D z = {Z(), {}}; } + +namespace GH69987 { +template struct X {}; +template struct X; +X x; + +template struct Y { Y(T); }; +template struct Y ; +Y y(1); +}; diff --git a/clang/test/VFS/Inputs/vfsoverlay.yaml b/clang/test/VFS/Inputs/vfsoverlay.yaml index 504a1530d3c55341ec0e474b5506538c7d25ea90..25ac53ea0ac77a4cbf2616cebe86531b38541b29 100644 --- a/clang/test/VFS/Inputs/vfsoverlay.yaml +++ b/clang/test/VFS/Inputs/vfsoverlay.yaml @@ -9,7 +9,7 @@ { 'name': 'import_some_frame.h', 'type': 'file', 'external-contents': 'INPUT_DIR/import_some_frame.h' }, - { 'name': 'module.map', 'type': 'file', + { 'name': 'module.modulemap', 'type': 'file', 'external-contents': 'INPUT_DIR/actual_module.map' }, { 'name': 'include_real.h', 'type': 'file', diff --git a/clang/test/VFS/Inputs/vfsoverlay2.yaml b/clang/test/VFS/Inputs/vfsoverlay2.yaml index ae2a0ce4ec98ff58b43ba8c3c5ad524e427a26d1..f6ed2710941bdd839776ea48b593f0aefd21ba04 100644 --- a/clang/test/VFS/Inputs/vfsoverlay2.yaml +++ b/clang/test/VFS/Inputs/vfsoverlay2.yaml @@ -3,7 +3,7 @@ 'roots': [ { 'name': 'OUT_DIR', 'type': 'directory', 'contents': [ - { 'name': 'module.map', 'type': 'file', + { 'name': 'module.modulemap', 'type': 'file', 'external-contents': 'INPUT_DIR/actual_module2.map' } ] diff --git a/clang/test/VFS/test_nonmodular.c b/clang/test/VFS/test_nonmodular.c index faec0e3a51623525bf4349f90408a116b10c242a..c7acb74f5eca2f01c99b5277da32c5f90d7228ad 100644 --- a/clang/test/VFS/test_nonmodular.c +++ b/clang/test/VFS/test_nonmodular.c @@ -1,6 +1,6 @@ // RUN: rm -rf %t // RUN: mkdir -p %t/vdir %t/cache %t/outdir -// We can't have module.map inside Inputs/Nonmodular. +// We can't have module.modulemap inside Inputs/Nonmodular. // RUN: cp %S/Inputs/Nonmodular/Nonmodular.modulemap %t/outdir/module.modulemap // // RUN: sed -e "s@VDIR@%{/t:regex_replacement}/vdir@g" -e "s@IN_DIR@%{/S:regex_replacement}@g" -e "s@OUT_DIR@%{/t:regex_replacement}/outdir@g" %S/Inputs/Nonmodular/nonmodular-headers.yaml > %t/vdir/nonmodular-headers.yaml diff --git a/clang/tools/arcmt-test/arcmt-test.cpp b/clang/tools/arcmt-test/arcmt-test.cpp index 53229ac570bc188fd40680d4be5f6d5c39e979d5..b61f38e9905dba7cfe8ac07229a7cb47e1feebb4 100644 --- a/clang/tools/arcmt-test/arcmt-test.cpp +++ b/clang/tools/arcmt-test/arcmt-test.cpp @@ -230,7 +230,7 @@ static bool verifyTransformedFiles(ArrayRef resultFiles) { for (ArrayRef::iterator I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) { StringRef fname(*I); - if (!fname.endswith(".result")) { + if (!fname.ends_with(".result")) { errs() << "error: filename '" << fname << "' does not have '.result' extension\n"; return true; diff --git a/clang/tools/c-arcmt-test/c-arcmt-test.c b/clang/tools/c-arcmt-test/c-arcmt-test.c index 3bbb2d5d6a8564ab1223cc4bd40e516a54da3bcf..00999f188c7dcedc1540b824394cb0e77c402bcb 100644 --- a/clang/tools/c-arcmt-test/c-arcmt-test.c +++ b/clang/tools/c-arcmt-test/c-arcmt-test.c @@ -1,8 +1,9 @@ /* c-arcmt-test.c */ #include "clang-c/Index.h" -#include +#include "llvm/Support/AutoConvert.h" #include +#include #include #if defined(_WIN32) #include @@ -107,6 +108,14 @@ static void flush_atexit(void) { } int main(int argc, const char **argv) { +#ifdef __MVS__ + if (enableAutoConversion(fileno(stdout)) == -1) + fprintf(stderr, "Setting conversion on stdout failed\n"); + + if (enableAutoConversion(fileno(stderr)) == -1) + fprintf(stderr, "Setting conversion on stderr failed\n"); +#endif + thread_info client_data; atexit(flush_atexit); diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 2c0c9cb8eb5e42fd701ad8a13d96a35f28dc7cd0..6fa400a0675b7a84e43712b6e3969d239e71117d 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -8,6 +8,7 @@ #include "clang-c/Documentation.h" #include "clang-c/Index.h" #include "clang/Config/config.h" +#include "llvm/Support/AutoConvert.h" #include #include #include @@ -5150,6 +5151,14 @@ static void flush_atexit(void) { int main(int argc, const char **argv) { thread_info client_data; +#ifdef __MVS__ + if (enableAutoConversion(fileno(stdout)) == -1) + fprintf(stderr, "Setting conversion on stdout failed\n"); + + if (enableAutoConversion(fileno(stderr)) == -1) + fprintf(stderr, "Setting conversion on stderr failed\n"); +#endif + atexit(flush_atexit); #ifdef CLANG_HAVE_LIBXML diff --git a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp index 769727eedec721612cdd81958321548db5a10b88..c048f335f91ca1e7c43fa5bf7e8813c5eb89bd55 100644 --- a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp +++ b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp @@ -181,7 +181,7 @@ static int HandleFiles(ArrayRef SourceFiles, // process them directly in HandleAST, otherwise put them // on a list for ClangTool to handle. for (StringRef Src : SourceFiles) { - if (Src.endswith(".ast")) { + if (Src.ends_with(".ast")) { if (!HandleAST(Src)) { return 1; } diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp index d2e3d8d43aef21a2f10bf094e0042138374fa633..be34dbbe886a157ba5c389732e63137c570626b7 100644 --- a/clang/tools/clang-format/ClangFormat.cpp +++ b/clang/tools/clang-format/ClangFormat.cpp @@ -12,6 +12,7 @@ /// //===----------------------------------------------------------------------===// +#include "../../lib/Format/MatchFilePath.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" @@ -570,6 +571,69 @@ static int dumpConfig(bool IsSTDIN) { return 0; } +// Check whether `FilePath` is ignored according to the nearest +// .clang-format-ignore file based on the rules below: +// - A blank line is skipped. +// - Leading and trailing spaces of a line are trimmed. +// - A line starting with a hash (`#`) is a comment. +// - A non-comment line is a single pattern. +// - The slash (`/`) is used as the directory separator. +// - A pattern is relative to the directory of the .clang-format-ignore file (or +// the root directory if the pattern starts with a slash). +// - A pattern is negated if it starts with a bang (`!`). +static bool isIgnored(StringRef FilePath) { + using namespace llvm::sys::fs; + if (!is_regular_file(FilePath)) + return false; + + using namespace llvm::sys::path; + SmallString<128> Path, AbsPath{FilePath}; + + make_absolute(AbsPath); + remove_dots(AbsPath, /*remove_dot_dot=*/true); + + StringRef IgnoreDir{AbsPath}; + do { + IgnoreDir = parent_path(IgnoreDir); + if (IgnoreDir.empty()) + return false; + + Path = IgnoreDir; + append(Path, ".clang-format-ignore"); + } while (!is_regular_file(Path)); + + std::ifstream IgnoreFile{Path.c_str()}; + if (!IgnoreFile.good()) + return false; + + const auto Pathname = convert_to_slash(AbsPath); + for (std::string Line; std::getline(IgnoreFile, Line);) { + auto Pattern = StringRef(Line).trim(); + if (Pattern.empty() || Pattern[0] == '#') + continue; + + const bool IsNegated = Pattern[0] == '!'; + if (IsNegated) + Pattern = Pattern.drop_front(); + + if (Pattern.empty()) + continue; + + Pattern = Pattern.ltrim(); + if (Pattern[0] != '/') { + Path = convert_to_slash(IgnoreDir); + append(Path, Style::posix, Pattern); + remove_dots(Path, /*remove_dot_dot=*/true, Style::posix); + Pattern = Path.str(); + } + + if (clang::format::matchFilePath(Pattern, Pathname) == !IsNegated) + return true; + } + + return false; +} + int main(int argc, const char **argv) { llvm::InitLLVM X(argc, argv); @@ -618,11 +682,14 @@ int main(int argc, const char **argv) { unsigned FileNo = 1; bool Error = false; for (const auto &FileName : FileNames) { + const bool IsSTDIN = FileName == "-"; + if (!IsSTDIN && isIgnored(FileName)) + continue; if (Verbose) { errs() << "Formatting [" << FileNo++ << "/" << FileNames.size() << "] " << FileName << "\n"; } - Error |= clang::format::format(FileName, FileName == "-"); + Error |= clang::format::format(FileName, IsSTDIN); } return Error ? 1 : 0; } diff --git a/clang/tools/clang-format/git-clang-format.bat b/clang/tools/clang-format/git-clang-format.bat index d4bc5172989cb098e2b1290b5c3906d590562911..9965cd4312fe39eec0d3395050f3d8664d373566 100644 --- a/clang/tools/clang-format/git-clang-format.bat +++ b/clang/tools/clang-format/git-clang-format.bat @@ -1 +1 @@ -py -3 git-clang-format %* +py -3 %~pn0 %* diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 5d2fe98fe56011588a4fa21748cd2c9bc10565a8..122ba1998eb83f6283829ac81afe3554db7e4999 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -396,11 +396,31 @@ Expected clang(ArrayRef InputFiles, const ArgList &Args) { CmdArgs.push_back("-Wl,-Bsymbolic"); CmdArgs.push_back("-shared"); ArgStringList LinkerArgs; - for (const opt::Arg *Arg : Args.filtered(OPT_library, OPT_library_path)) - Arg->render(Args, LinkerArgs); - for (const opt::Arg *Arg : Args.filtered(OPT_rpath)) - LinkerArgs.push_back( - Args.MakeArgString("-Wl,-rpath," + StringRef(Arg->getValue()))); + for (const opt::Arg *Arg : + Args.filtered(OPT_INPUT, OPT_library, OPT_library_path, OPT_rpath, + OPT_whole_archive, OPT_no_whole_archive)) { + // Sometimes needed libraries are passed by name, such as when using + // sanitizers. We need to check the file magic for any libraries. + if (Arg->getOption().matches(OPT_INPUT)) { + if (!sys::fs::exists(Arg->getValue()) || + sys::fs::is_directory(Arg->getValue())) + continue; + + file_magic Magic; + if (auto EC = identify_magic(Arg->getValue(), Magic)) + return createStringError(inconvertibleErrorCode(), + "Failed to open %s", Arg->getValue()); + if (Magic != file_magic::archive && + Magic != file_magic::elf_shared_object) + continue; + } + if (Arg->getOption().matches(OPT_whole_archive)) + LinkerArgs.push_back(Args.MakeArgString("-Wl,--whole-archive")); + else if (Arg->getOption().matches(OPT_no_whole_archive)) + LinkerArgs.push_back(Args.MakeArgString("-Wl,--no-whole-archive")); + else + Arg->render(Args, LinkerArgs); + } llvm::copy(LinkerArgs, std::back_inserter(CmdArgs)); } @@ -526,7 +546,6 @@ std::unique_ptr createLTO( Conf.CPU = Arch.str(); Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple); - Conf.Freestanding = true; StringRef OptLevel = Args.getLastArgValue(OPT_opt_level, "O2"); Conf.MAttrs = Features; @@ -1151,7 +1170,7 @@ linkAndWrapDeviceFiles(SmallVectorImpl &LinkerInputFiles, std::optional findFile(StringRef Dir, StringRef Root, const Twine &Name) { SmallString<128> Path; - if (Dir.startswith("=")) + if (Dir.starts_with("=")) sys::path::append(Path, Root, Dir.substr(1), Name); else sys::path::append(Path, Dir, Name); @@ -1188,7 +1207,7 @@ searchLibraryBaseName(StringRef Name, StringRef Root, /// `-lfoo` or `-l:libfoo.a`. std::optional searchLibrary(StringRef Input, StringRef Root, ArrayRef SearchPaths) { - if (Input.startswith(":") || Input.ends_with(".lib")) + if (Input.starts_with(":") || Input.ends_with(".lib")) return findFromSearchPaths(Input.drop_front(), Root, SearchPaths); return searchLibraryBaseName(Input, Root, SearchPaths); } diff --git a/clang/tools/clang-refactor/ClangRefactor.cpp b/clang/tools/clang-refactor/ClangRefactor.cpp index d362eecf06d8a5a62193ff9826f41b20478f32be..175a2b8234e9acd9c8efb1f1661c14c6381af409 100644 --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -146,7 +146,7 @@ private: std::unique_ptr SourceSelectionArgument::fromString(StringRef Value) { - if (Value.startswith("test:")) { + if (Value.starts_with("test:")) { StringRef Filename = Value.drop_front(strlen("test:")); std::optional ParsedTestSelection = findTestSelectionRanges(Filename); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index 5663c2c5a6c9285450cbc850741e4e45afc11b49..5bad8145324d06370762cc5ed03d8b3b11e96a18 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -15,6 +15,8 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Interpreter/CodeCompletion.h" #include "clang/Interpreter/Interpreter.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Sema/Sema.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/LineEditor/LineEditor.h" @@ -123,22 +125,14 @@ ReplListCompleter::operator()(llvm::StringRef Buffer, size_t Pos, return {}; } - - codeComplete( - const_cast((*Interp)->getCompilerInstance()), - Buffer, Lines, Pos + 1, MainInterp.getCompilerInstance(), Results); - - size_t space_pos = Buffer.rfind(" "); - llvm::StringRef Prefix; - if (space_pos == llvm::StringRef::npos) { - Prefix = Buffer; - } else { - Prefix = Buffer.substr(space_pos + 1); - } - + auto *MainCI = (*Interp)->getCompilerInstance(); + auto CC = clang::ReplCodeCompleter(); + CC.codeComplete(MainCI, Buffer, Lines, Pos + 1, + MainInterp.getCompilerInstance(), Results); for (auto c : Results) { - if (c.find(Prefix) == 0) - Comps.push_back(llvm::LineEditor::Completion(c.substr(Prefix.size()), c)); + if (c.find(CC.Prefix) == 0) + Comps.push_back( + llvm::LineEditor::Completion(c.substr(CC.Prefix.size()), c)); } return Comps; } @@ -234,7 +228,7 @@ int main(int argc, const char **argv) { while (std::optional Line = LE.readLine()) { llvm::StringRef L = *Line; L = L.trim(); - if (L.endswith("\\")) { + if (L.ends_with("\\")) { // FIXME: Support #ifdef X \ ... Input += L.drop_back(1); LE.setPrompt("clang-repl... "); diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index f11c933d9576565a91a936121988f78ce2ecb149..75aa4ae97c618c4efc13104eec2ff267a0b18405 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -830,9 +830,9 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { // Also, clang-cl adds ".obj" extension if none is found. if ((Arg == "-o" || Arg == "/o") && I != R) LastO = I[-1]; // Next argument (reverse iterator) - else if (Arg.startswith("/Fo") || Arg.startswith("-Fo")) + else if (Arg.starts_with("/Fo") || Arg.starts_with("-Fo")) LastO = Arg.drop_front(3).str(); - else if (Arg.startswith("/o") || Arg.startswith("-o")) + else if (Arg.starts_with("/o") || Arg.starts_with("-o")) LastO = Arg.drop_front(2).str(); if (!LastO.empty() && !llvm::sys::path::has_extension(LastO)) diff --git a/clang/tools/diagtool/TreeView.cpp b/clang/tools/diagtool/TreeView.cpp index 4f5d3fd3ef0a89c8869fc83e097acc94efedbcef..eae16243d3d59cb42f296b8807c4e42ff01d9dee 100644 --- a/clang/tools/diagtool/TreeView.cpp +++ b/clang/tools/diagtool/TreeView.cpp @@ -160,7 +160,7 @@ int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) { break; case 1: RootGroup = argv[0]; - if (RootGroup.startswith("-W")) + if (RootGroup.starts_with("-W")) RootGroup = RootGroup.substr(2); if (RootGroup == "everything") ShowAll = true; diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 531b5b4a61c1804452918c3caab702440a3571e6..4adc7f7ad0dac397c26fe126030ea2a3728569c5 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -122,7 +122,7 @@ static void ApplyOneQAOverride(raw_ostream &OS, GetStableCStr(SavedStrings, Edit.substr(1)); OS << "### Adding argument " << Str << " at end\n"; Args.push_back(Str); - } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") && + } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.ends_with("/") && Edit.slice(2, Edit.size() - 1).contains('/')) { StringRef MatchPattern = Edit.substr(2).split('/').first; StringRef ReplPattern = Edit.substr(2).split('/').second; @@ -403,7 +403,7 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { } // Handle -cc1 integrated tools. - if (Args.size() >= 2 && StringRef(Args[1]).startswith("-cc1")) + if (Args.size() >= 2 && StringRef(Args[1]).starts_with("-cc1")) return ExecuteCC1Tool(Args, ToolContext); // Handle options that need handling before the real command line parsing in diff --git a/clang/tools/libclang/CIndexUSRs.cpp b/clang/tools/libclang/CIndexUSRs.cpp index 75bb3b01299f10b16f8f9290db1b2d6c13aac333..be7c670cca0113617ef07b874ff875f96bc9dc4e 100644 --- a/clang/tools/libclang/CIndexUSRs.cpp +++ b/clang/tools/libclang/CIndexUSRs.cpp @@ -28,7 +28,7 @@ using namespace clang::index; //===----------------------------------------------------------------------===// static inline StringRef extractUSRSuffix(StringRef s) { - return s.startswith("c:") ? s.substr(2) : ""; + return s.starts_with("c:") ? s.substr(2) : ""; } bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl &Buf) { diff --git a/clang/tools/libclang/CIndexer.cpp b/clang/tools/libclang/CIndexer.cpp index 77da2e4fa5ead0ff29c6a3f473acdeb518dc8462..12d9d418dea51db573519a52c7265e0858048ee9 100644 --- a/clang/tools/libclang/CIndexer.cpp +++ b/clang/tools/libclang/CIndexer.cpp @@ -14,6 +14,7 @@ #include "CXString.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Version.h" +#include "clang/Config/config.h" #include "clang/Driver/Driver.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" @@ -125,21 +126,28 @@ const std::string &CIndexer::getClangResourcesPath() { #elif defined(_AIX) getClangResourcesPathImplAIX(LibClangPath); #else + bool PathFound = false; +#if defined(CLANG_HAVE_DLFCN_H) && defined(CLANG_HAVE_DLADDR) Dl_info info; - std::string Path; // This silly cast below avoids a C++ warning. if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) != 0) { // We now have the CIndex directory, locate clang relative to it. LibClangPath += info.dli_fname; - } else if (!(Path = llvm::sys::fs::getMainExecutable(nullptr, nullptr)).empty()) { - // If we can't get the path using dladdr, try to get the main executable - // path. This may be needed when we're statically linking libclang with - // musl libc, for example. - LibClangPath += Path; - } else { - // It's rather unlikely we end up here. But it could happen, so report an - // error instead of crashing. - llvm::report_fatal_error("could not locate Clang resource path"); + PathFound = true; + } +#endif + std::string Path; + if (!PathFound) { + if (!(Path = llvm::sys::fs::getMainExecutable(nullptr, nullptr)).empty()) { + // If we can't get the path using dladdr, try to get the main executable + // path. This may be needed when we're statically linking libclang with + // musl libc, for example. + LibClangPath += Path; + } else { + // It's rather unlikely we end up here. But it could happen, so report an + // error instead of crashing. + llvm::report_fatal_error("could not locate Clang resource path"); + } } #endif diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 4dd7510bf8ddf810bcaa9b8d14cfc266046aadfc..ed8ecb080e268d6f240ae70c85246ea3d1d59c7c 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -561,6 +561,18 @@ TEST_P(ImportExpr, ImportVAArgExpr) { cStyleCastExpr(hasSourceExpression(vaArgExpr()))))); } +const internal::VariadicDynCastAllOfMatcher + builtinBitCastExpr; + +TEST_P(ImportExpr, ImportBuiltinBitCastExpr) { + MatchVerifier Verifier; + testImport("void declToImport(int X) {" + " (void)__builtin_bit_cast(float, X); }", + Lang_CXX20, "", Lang_CXX20, Verifier, + functionDecl(hasDescendant( + cStyleCastExpr(hasSourceExpression(builtinBitCastExpr()))))); +} + TEST_P(ImportExpr, CXXTemporaryObjectExpr) { MatchVerifier Verifier; testImport( @@ -7250,6 +7262,26 @@ TEST_P(ImportAutoFunctions, ReturnWithAutoTemplateType) { Lang_CXX14, /*FindLast=*/true); } +TEST_P(ImportAutoFunctions, ReturnWithSubstNonTypeTemplateParmExpr) { + const char *Code = + R"( + template + struct array {}; + + template + auto foo() { return array(); } + + void bar() { foo<0>(); } + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX17); + + auto *FromBar = FirstDeclMatcher().match( + FromTU, functionDecl(hasName("bar"))); + + auto *ToBar = Import(FromBar, Lang_CXX17); + EXPECT_TRUE(ToBar); +} + struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {}; TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) { @@ -7425,67 +7457,46 @@ void ImportAttributes::checkImported(const Decl *From, const Decl *To) { ToAST->getASTContext().getTranslationUnitDecl()); } -// FIXME: Use ImportAttributes for this test. -TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) { - // Test if import of these packed and aligned attributes does not trigger an - // error situation where source location from 'From' context is referenced in - // 'To' context through evaluation of the alignof attribute. - // This happens if the 'alignof(A)' expression is not imported correctly. - Decl *FromTU = getTuDecl( +TEST_P(ImportAttributes, ImportAligned) { + AlignedAttr *FromAttr, *ToAttr; + importAttr( R"( struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; }; - struct alignas(alignof(A)) S {}; + struct alignas(alignof(A)) test {}; )", - Lang_CXX11, "input.cc"); - auto *FromD = FirstDeclMatcher().match( - FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit()))); - ASSERT_TRUE(FromD); - - auto *ToD = Import(FromD, Lang_CXX11); - ASSERT_TRUE(ToD); - - auto *FromAttr = FromD->getAttr(); - auto *ToAttr = ToD->getAttr(); - EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); - EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); - EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); - EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); - EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling()); - EXPECT_TRUE(ToAttr->getAlignmentExpr()); + FromAttr, ToAttr); + checkImported(FromAttr->getAlignmentExpr(), ToAttr->getAlignmentExpr()); auto *ToA = FirstDeclMatcher().match( - ToD->getTranslationUnitDecl(), + ToAST->getASTContext().getTranslationUnitDecl(), cxxRecordDecl(hasName("A"), unless(isImplicit()))); // Ensure that 'struct A' was imported (through reference from attribute of - // 'S'). + // struct 'test'). EXPECT_TRUE(ToA); } -// FIXME: Use ImportAttributes for this test. -TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) { - Decl *FromTU = getTuDecl( +TEST_P(ImportAttributes, ImportAlignValue) { + AlignValueAttr *FromAttr, *ToAttr; + importAttr( R"( - int foo(const char * fmt, ...) + void *test __attribute__((align_value(64))); + )", + FromAttr, ToAttr); + checkImported(FromAttr->getAlignment(), ToAttr->getAlignment()); +} + +TEST_P(ImportAttributes, ImportFormat) { + FormatAttr *FromAttr, *ToAttr; + importAttr( + R"( + int test(const char * fmt, ...) __attribute__ ((__format__ (__scanf__, 1, 2))); )", - Lang_CXX03, "input.cc"); - auto *FromD = FirstDeclMatcher().match( - FromTU, functionDecl(hasName("foo"))); - ASSERT_TRUE(FromD); + FromAttr, ToAttr); - auto *ToD = Import(FromD, Lang_CXX03); - ASSERT_TRUE(ToD); - ToD->dump(); // Should not crash! - - auto *FromAttr = FromD->getAttr(); - auto *ToAttr = ToD->getAttr(); - EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited()); - EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion()); - EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit()); - EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax()); - EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(), - ToAttr->getAttributeSpellingListIndex()); EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); + EXPECT_EQ(FromAttr->getFirstArg(), ToAttr->getFirstArg()); + EXPECT_EQ(FromAttr->getFormatIdx(), ToAttr->getFormatIdx()); } TEST_P(ImportAttributes, ImportEnableIf) { @@ -9284,6 +9295,53 @@ TEST_P(ASTImporterOptionSpecificTestBase, // EXPECT_EQ(ToF1Imported->getPreviousDecl(), ToF1); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportTypeAliasTemplateAfterSimilarCalledTemplateTypeParm) { + const char *Code = + R"( + struct S; + template + using Callable = S; + template + int bindingFunctionVTable; + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX17); + + auto *FromCallable = FirstDeclMatcher().match( + FromTU, typeAliasTemplateDecl(hasName("Callable"))); + + auto *FromCallableParm = FirstDeclMatcher().match( + FromTU, templateTypeParmDecl(hasName("Callable"))); + + auto *ToFromCallableParm = Import(FromCallableParm, Lang_CXX17); + auto *ToCallable = Import(FromCallable, Lang_CXX17); + EXPECT_TRUE(ToFromCallableParm); + EXPECT_TRUE(ToCallable); +} + +TEST_P(ASTImporterOptionSpecificTestBase, ImportConflictTypeAliasTemplate) { + const char *ToCode = + R"( + struct S; + template + using Callable = S; + )"; + const char *Code = + R"( + struct S; + template + using Callable = S; + )"; + (void)getToTuDecl(ToCode, Lang_CXX17); + Decl *FromTU = getTuDecl(Code, Lang_CXX17); + + auto *FromCallable = FirstDeclMatcher().match( + FromTU, typeAliasTemplateDecl(hasName("Callable"))); + + auto *ImportedCallable = Import(FromCallable, Lang_CXX17); + EXPECT_FALSE(ImportedCallable); +} + INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions); diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp index fe65fab98c5ed47a3b900958e19976b20b84f2c4..738f6efd2018d77733520848fe987b0a9a5b107c 100644 --- a/clang/unittests/Analysis/CloneDetectionTest.cpp +++ b/clang/unittests/Analysis/CloneDetectionTest.cpp @@ -42,7 +42,7 @@ public: for (const StmtSequence &Arg : {A, B}) { if (const auto *D = dyn_cast(Arg.getContainingDecl())) { - if (D->getName().startswith("bar")) + if (D->getName().starts_with("bar")) return false; } } diff --git a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp index 84fe675c32c2d0be37807664c555f3cc33811db2..cd6a37d370e854fd0f7344e3413642ddb3d7cf8f 100644 --- a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp @@ -89,8 +89,6 @@ TEST(RecordOpsTest, CopyRecord) { auto *S2Val = cast(Env.getValue(S2)); EXPECT_NE(S1Val, S2Val); - S1Val->setProperty("prop", Env.getBoolLiteralValue(true)); - copyRecord(S1, S2, Env); EXPECT_EQ(getFieldValue(&S1, *OuterIntDecl, Env), @@ -104,8 +102,6 @@ TEST(RecordOpsTest, CopyRecord) { S1Val = cast(Env.getValue(S1)); S2Val = cast(Env.getValue(S2)); EXPECT_NE(S1Val, S2Val); - - EXPECT_EQ(S2Val->getProperty("prop"), &Env.getBoolLiteralValue(true)); }); } @@ -150,9 +146,6 @@ TEST(RecordOpsTest, RecordsEqual) { Env.setValue(S1.getSyntheticField("synth_int"), Env.create()); - cast(Env.getValue(S1)) - ->setProperty("prop", Env.getBoolLiteralValue(true)); - // Strategy: Create two equal records, then verify each of the various // ways in which records can differ causes recordsEqual to return false. // changes we can make to the record. @@ -202,36 +195,6 @@ TEST(RecordOpsTest, RecordsEqual) { EXPECT_FALSE(recordsEqual(S1, S2, Env)); copyRecord(S1, S2, Env); EXPECT_TRUE(recordsEqual(S1, S2, Env)); - - // S1 and S2 have the same property with different values. - cast(Env.getValue(S2)) - ->setProperty("prop", Env.getBoolLiteralValue(false)); - EXPECT_FALSE(recordsEqual(S1, S2, Env)); - copyRecord(S1, S2, Env); - EXPECT_TRUE(recordsEqual(S1, S2, Env)); - - // S1 has a property that S2 doesn't have. - cast(Env.getValue(S1)) - ->setProperty("other_prop", Env.getBoolLiteralValue(false)); - EXPECT_FALSE(recordsEqual(S1, S2, Env)); - // We modified S1 this time, so need to copy back the other way. - copyRecord(S2, S1, Env); - EXPECT_TRUE(recordsEqual(S1, S2, Env)); - - // S2 has a property that S1 doesn't have. - cast(Env.getValue(S2)) - ->setProperty("other_prop", Env.getBoolLiteralValue(false)); - EXPECT_FALSE(recordsEqual(S1, S2, Env)); - copyRecord(S1, S2, Env); - EXPECT_TRUE(recordsEqual(S1, S2, Env)); - - // S1 and S2 have the same number of properties, but with different - // names. - cast(Env.getValue(S1)) - ->setProperty("prop1", Env.getBoolLiteralValue(false)); - cast(Env.getValue(S2)) - ->setProperty("prop2", Env.getBoolLiteralValue(false)); - EXPECT_FALSE(recordsEqual(S1, S2, Env)); }); } diff --git a/clang/unittests/Analysis/FlowSensitive/SignAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/SignAnalysisTest.cpp index 362b0dea58d6b80d2b03a12806e4655aa1ae6a8c..b5fc7bbc431eaeefa0502cb778d1f74ac0cfd7aa 100644 --- a/clang/unittests/Analysis/FlowSensitive/SignAnalysisTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/SignAnalysisTest.cpp @@ -133,7 +133,7 @@ void transferBinary(const BinaryOperator *BO, const MatchFinder::MatchResult &M, LatticeTransferState &State) { auto &A = State.Env.arena(); const Formula *Comp; - if (BoolValue *V = cast_or_null(State.Env.getValue(*BO))) { + if (BoolValue *V = State.Env.get(*BO)) { Comp = &V->formula(); } else { Comp = &A.makeAtomRef(A.makeAtom()); diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 8da55953a3298698094bb58fd1f4152374ceb06b..056c4f3383d832261291e2583ab1a300a88f5ec0 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2635,6 +2635,55 @@ TEST(TransferTest, BindTemporary) { }); } +TEST(TransferTest, ResultObjectLocation) { + std::string Code = R"( + struct A { + virtual ~A() = default; + }; + + void target() { + A(); + (void)0; // [[p]] + } + )"; + using ast_matchers::cxxBindTemporaryExpr; + using ast_matchers::cxxTemporaryObjectExpr; + using ast_matchers::exprWithCleanups; + using ast_matchers::has; + using ast_matchers::match; + using ast_matchers::selectFirst; + using ast_matchers::traverse; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + // The expresssion `A()` in the code above produces the following + // structure, consisting of three prvalues of record type. + // `Env.getResultObjectLocation()` should return the same location for + // all of these. + auto MatchResult = match( + traverse(TK_AsIs, + exprWithCleanups( + has(cxxBindTemporaryExpr( + has(cxxTemporaryObjectExpr().bind("toe"))) + .bind("bte"))) + .bind("ewc")), + ASTCtx); + auto *TOE = selectFirst("toe", MatchResult); + ASSERT_NE(TOE, nullptr); + auto *EWC = selectFirst("ewc", MatchResult); + ASSERT_NE(EWC, nullptr); + auto *BTE = selectFirst("bte", MatchResult); + ASSERT_NE(BTE, nullptr); + + RecordStorageLocation &Loc = Env.getResultObjectLocation(*TOE); + EXPECT_EQ(&Loc, &Env.getResultObjectLocation(*EWC)); + EXPECT_EQ(&Loc, &Env.getResultObjectLocation(*BTE)); + }); +} + TEST(TransferTest, StaticCast) { std::string Code = R"( void target(int Foo) { diff --git a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp index 4c3cb322eacfb3a3b018d5c3fc8a6275255aa278..8d481788af208a0fde66d82374f0200e27e96b1d 100644 --- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp @@ -623,11 +623,11 @@ TEST_F(JoinFlowConditionsTest, JoinDistinctButProvablyEquivalentValues) { }); } -class OptionalIntAnalysis final - : public DataflowAnalysis { +class NullPointerAnalysis final + : public DataflowAnalysis { public: - explicit OptionalIntAnalysis(ASTContext &Context) - : DataflowAnalysis(Context) {} + explicit NullPointerAnalysis(ASTContext &Context) + : DataflowAnalysis(Context) {} static NoopLattice initialElement() { return {}; } @@ -636,40 +636,37 @@ public: if (!CS) return; const Stmt *S = CS->getStmt(); - auto OptionalIntRecordDecl = recordDecl(hasName("OptionalInt")); - auto HasOptionalIntType = hasType(OptionalIntRecordDecl); - - SmallVector Matches = match( - stmt(anyOf(cxxConstructExpr(HasOptionalIntType).bind("construct"), - cxxOperatorCallExpr( - callee(cxxMethodDecl(ofClass(OptionalIntRecordDecl)))) - .bind("operator"))), - *S, getASTContext()); - if (const auto *E = selectFirst( - "construct", Matches)) { - cast(Env.getValue(*E)) - ->setProperty("has_value", Env.getBoolLiteralValue(false)); - } else if (const auto *E = - selectFirst("operator", Matches)) { - assert(E->getNumArgs() > 0); - auto *Object = E->getArg(0); - assert(Object != nullptr); - - refreshRecordValue(*Object, Env) - .setProperty("has_value", Env.getBoolLiteralValue(true)); + const Expr *E = dyn_cast(S); + if (!E) + return; + + if (!E->getType()->isPointerType()) + return; + + // Make sure we have a `PointerValue` for `E`. + auto *PtrVal = cast_or_null(Env.getValue(*E)); + if (PtrVal == nullptr) { + PtrVal = cast(Env.createValue(E->getType())); + Env.setValue(*E, *PtrVal); } + + if (auto *Cast = dyn_cast(E); + Cast && Cast->getCastKind() == CK_NullToPointer) + PtrVal->setProperty("is_null", Env.getBoolLiteralValue(true)); + else if (auto *Op = dyn_cast(E); + Op && Op->getOpcode() == UO_AddrOf) + PtrVal->setProperty("is_null", Env.getBoolLiteralValue(false)); } ComparisonResult compare(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2) override { - // Nothing to say about a value that does not model an `OptionalInt`. - if (!Type->isRecordType() || - Type->getAsCXXRecordDecl()->getQualifiedNameAsString() != "OptionalInt") + // Nothing to say about a value that is not a pointer. + if (!Type->isPointerType()) return ComparisonResult::Unknown; - auto *Prop1 = Val1.getProperty("has_value"); - auto *Prop2 = Val2.getProperty("has_value"); + auto *Prop1 = Val1.getProperty("is_null"); + auto *Prop2 = Val2.getProperty("is_null"); assert(Prop1 != nullptr && Prop2 != nullptr); return areEquivalentValues(*Prop1, *Prop2) ? ComparisonResult::Same : ComparisonResult::Different; @@ -678,23 +675,22 @@ public: bool merge(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2, Value &MergedVal, Environment &MergedEnv) override { - // Nothing to say about a value that does not model an `OptionalInt`. - if (!Type->isRecordType() || - Type->getAsCXXRecordDecl()->getQualifiedNameAsString() != "OptionalInt") + // Nothing to say about a value that is not a pointer. + if (!Type->isPointerType()) return false; - auto *HasValue1 = cast_or_null(Val1.getProperty("has_value")); - if (HasValue1 == nullptr) + auto *IsNull1 = cast_or_null(Val1.getProperty("is_null")); + if (IsNull1 == nullptr) return false; - auto *HasValue2 = cast_or_null(Val2.getProperty("has_value")); - if (HasValue2 == nullptr) + auto *IsNull2 = cast_or_null(Val2.getProperty("is_null")); + if (IsNull2 == nullptr) return false; - if (HasValue1 == HasValue2) - MergedVal.setProperty("has_value", *HasValue1); + if (IsNull1 == IsNull2) + MergedVal.setProperty("is_null", *IsNull1); else - MergedVal.setProperty("has_value", MergedEnv.makeTopBoolValue()); + MergedVal.setProperty("is_null", MergedEnv.makeTopBoolValue()); return true; } }; @@ -703,23 +699,14 @@ class WideningTest : public Test { protected: template void runDataflow(llvm::StringRef Code, Matcher Match) { - tooling::FileContentMappings FilesContents; - FilesContents.push_back( - std::make_pair("widening_test_defs.h", R"( - struct OptionalInt { - OptionalInt() = default; - OptionalInt& operator=(int); - }; - )")); ASSERT_THAT_ERROR( - checkDataflow( - AnalysisInputs( + checkDataflow( + AnalysisInputs( Code, ast_matchers::hasName("target"), [](ASTContext &Context, Environment &Env) { - return OptionalIntAnalysis(Context); + return NullPointerAnalysis(Context); }) - .withASTBuildArgs({"-fsyntax-only", "-std=c++17"}) - .withASTBuildVirtualMappedFiles(std::move(FilesContents)), + .withASTBuildArgs({"-fsyntax-only", "-std=c++17"}), /*VerifyResults=*/[&Match](const llvm::StringMap< DataflowAnalysisState> &Results, @@ -731,13 +718,12 @@ protected: TEST_F(WideningTest, JoinDistinctValuesWithDistinctProperties) { std::string Code = R"( - #include "widening_test_defs.h" - void target(bool Cond) { - OptionalInt Foo; + int *Foo = nullptr; + int i = 0; /*[[p1]]*/ if (Cond) { - Foo = 1; + Foo = &i; /*[[p2]]*/ } (void)0; @@ -760,27 +746,27 @@ TEST_F(WideningTest, JoinDistinctValuesWithDistinctProperties) { return Env.getValue(*FooDecl); }; - EXPECT_EQ(GetFooValue(Env1)->getProperty("has_value"), - &Env1.getBoolLiteralValue(false)); - EXPECT_EQ(GetFooValue(Env2)->getProperty("has_value"), - &Env2.getBoolLiteralValue(true)); + EXPECT_EQ(GetFooValue(Env1)->getProperty("is_null"), + &Env1.getBoolLiteralValue(true)); + EXPECT_EQ(GetFooValue(Env2)->getProperty("is_null"), + &Env2.getBoolLiteralValue(false)); EXPECT_TRUE( - isa(GetFooValue(Env3)->getProperty("has_value"))); + isa(GetFooValue(Env3)->getProperty("is_null"))); }); } TEST_F(WideningTest, JoinDistinctValuesWithSameProperties) { std::string Code = R"( - #include "widening_test_defs.h" - void target(bool Cond) { - OptionalInt Foo; + int *Foo = nullptr; + int i1 = 0; + int i2 = 0; /*[[p1]]*/ if (Cond) { - Foo = 1; + Foo = &i1; /*[[p2]]*/ } else { - Foo = 2; + Foo = &i2; /*[[p3]]*/ } (void)0; @@ -805,14 +791,14 @@ TEST_F(WideningTest, JoinDistinctValuesWithSameProperties) { return Env.getValue(*FooDecl); }; - EXPECT_EQ(GetFooValue(Env1)->getProperty("has_value"), - &Env1.getBoolLiteralValue(false)); - EXPECT_EQ(GetFooValue(Env2)->getProperty("has_value"), - &Env2.getBoolLiteralValue(true)); - EXPECT_EQ(GetFooValue(Env3)->getProperty("has_value"), - &Env3.getBoolLiteralValue(true)); - EXPECT_EQ(GetFooValue(Env4)->getProperty("has_value"), - &Env4.getBoolLiteralValue(true)); + EXPECT_EQ(GetFooValue(Env1)->getProperty("is_null"), + &Env1.getBoolLiteralValue(true)); + EXPECT_EQ(GetFooValue(Env2)->getProperty("is_null"), + &Env2.getBoolLiteralValue(false)); + EXPECT_EQ(GetFooValue(Env3)->getProperty("is_null"), + &Env3.getBoolLiteralValue(false)); + EXPECT_EQ(GetFooValue(Env4)->getProperty("is_null"), + &Env4.getBoolLiteralValue(false)); }); } @@ -849,13 +835,13 @@ TEST_F(WideningTest, DistinctPointersToTheSameLocationAreEquivalent) { TEST_F(WideningTest, DistinctValuesWithSamePropertiesAreEquivalent) { std::string Code = R"( - #include "widening_test_defs.h" - void target(bool Cond) { - OptionalInt Foo; - Foo = 1; + int *Foo; + int i1 = 0; + int i2 = 0; + Foo = &i1; while (Cond) { - Foo = 2; + Foo = &i2; } (void)0; /*[[p]]*/ @@ -872,8 +858,8 @@ TEST_F(WideningTest, DistinctValuesWithSamePropertiesAreEquivalent) { ASSERT_THAT(FooDecl, NotNull()); const auto *FooVal = Env.getValue(*FooDecl); - EXPECT_EQ(FooVal->getProperty("has_value"), - &Env.getBoolLiteralValue(true)); + EXPECT_EQ(FooVal->getProperty("is_null"), + &Env.getBoolLiteralValue(false)); }); } diff --git a/clang/unittests/Driver/ModuleCacheTest.cpp b/clang/unittests/Driver/ModuleCacheTest.cpp index 6a0f68f26a6767a96688cc362756d20fd3c6bf2d..48744415647e68471f53bbb8827b55a5669a42b9 100644 --- a/clang/unittests/Driver/ModuleCacheTest.cpp +++ b/clang/unittests/Driver/ModuleCacheTest.cpp @@ -22,6 +22,6 @@ TEST(ModuleCacheTest, GetTargetAndMode) { Driver::getDefaultModuleCachePath(Buf); StringRef Path = Buf; EXPECT_TRUE(Path.find("clang") != Path.npos); - EXPECT_TRUE(Path.endswith("ModuleCache")); + EXPECT_TRUE(Path.ends_with("ModuleCache")); } } // end anonymous namespace. diff --git a/clang/unittests/Driver/MultilibBuilderTest.cpp b/clang/unittests/Driver/MultilibBuilderTest.cpp index 60fe10ac3ba556e9851f474635517727a5226b01..e23fe7e2441db534148ca3b54191e99f88e45b97 100644 --- a/clang/unittests/Driver/MultilibBuilderTest.cpp +++ b/clang/unittests/Driver/MultilibBuilderTest.cpp @@ -144,7 +144,7 @@ TEST(MultilibBuilderTest, SetFilterObject) { << "Size before filter was incorrect. Contents:\n" << MS; MS.FilterOut([](const Multilib &M) { - return StringRef(M.gccSuffix()).startswith("/p"); + return StringRef(M.gccSuffix()).starts_with("/p"); }); ASSERT_EQ((int)MS.size(), 1 /* Default */ + 1 /* orange */ + 1 /* orange/pear */ + 1 /* orange/plum */ + @@ -152,7 +152,7 @@ TEST(MultilibBuilderTest, SetFilterObject) { << "Size after filter was incorrect. Contents:\n" << MS; for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) { - ASSERT_FALSE(StringRef(I->gccSuffix()).startswith("/p")) + ASSERT_FALSE(StringRef(I->gccSuffix()).starts_with("/p")) << "The filter should have removed " << *I; } } diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp index acbbb87390d5e9ae3a26586ac290f34059bd671c..a9b5f3c700315c49d0234587edfa2f61a7cedab8 100644 --- a/clang/unittests/Driver/ToolChainTest.cpp +++ b/clang/unittests/Driver/ToolChainTest.cpp @@ -531,7 +531,7 @@ TEST(ToolChainTest, CommandOutput) { const auto &InFile = CmdCompile->getInputInfos().front().getFilename(); EXPECT_STREQ(InFile, "foo.cpp"); auto ObjFile = CmdCompile->getOutputFilenames().front(); - EXPECT_TRUE(StringRef(ObjFile).endswith(".o")); + EXPECT_TRUE(StringRef(ObjFile).ends_with(".o")); const auto &CmdLink = Jobs.getJobs().back(); const auto LinkInFile = CmdLink->getInputInfos().front().getFilename(); diff --git a/clang/unittests/Format/CMakeLists.txt b/clang/unittests/Format/CMakeLists.txt index 53136328928f5c7d655201c266ef7237d801e308..71f5886d946c805b49e6ba9d44d747cab515a0bf 100644 --- a/clang/unittests/Format/CMakeLists.txt +++ b/clang/unittests/Format/CMakeLists.txt @@ -27,6 +27,7 @@ add_clang_unittest(FormatTests IntegerLiteralSeparatorTest.cpp MacroCallReconstructorTest.cpp MacroExpanderTest.cpp + MatchFilePathTest.cpp NamespaceEndCommentsFixerTest.cpp ObjCPropertyAttributeOrderFixerTest.cpp QualifierFixerTest.cpp diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 24b2fd599dc39733911c56a2a7cf64d0ffb8a189..881993ede17c3dc153070c3fa282beeb26289352 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "FormatTestBase.h" +#include "gmock/gmock.h" #define DEBUG_TYPE "format-test" @@ -4571,6 +4572,13 @@ TEST_F(FormatTest, IndentExternBlockStyle) { "}", Style); + Style.BreakBeforeBraces = FormatStyle::BS_Allman; + verifyFormat("extern \"C\"\n" + "{\n" + "int i;\n" + "}", + Style); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; Style.BraceWrapping.AfterExternBlock = true; Style.IndentExternBlock = FormatStyle::IEBS_Indent; @@ -8490,7 +8498,10 @@ TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) { " __attribute__((unused));"); Style = getGoogleStyle(); - Style.AttributeMacros.push_back("GUARDED_BY"); + ASSERT_THAT(Style.AttributeMacros, + testing::AllOf(testing::Contains("GUARDED_BY"), + testing::Contains("ABSL_GUARDED_BY"))); + verifyFormat( "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " GUARDED_BY(aaaaaaaaaaaa);", @@ -8507,6 +8518,23 @@ TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) { "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n" " aaaaaaaaaaaaaaaaaaaaaaaaa;", Style); + + verifyFormat( + "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " ABSL_GUARDED_BY(aaaaaaaaaaaa);", + Style); + verifyFormat( + "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " ABSL_GUARDED_BY(aaaaaaaaaaaa);", + Style); + verifyFormat( + "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ABSL_GUARDED_BY(aaaaaaaaaaaa) =\n" + " aaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;", + Style); + verifyFormat( + "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ABSL_GUARDED_BY(aaaaaaaaaaaa) =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;", + Style); } TEST_F(FormatTest, FunctionAnnotations) { @@ -10065,11 +10093,11 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) { getGoogleStyleWithColumns(40)); verifyFormat("Tttttttttttttttttttttttt ppppppppppppppp\n" " ABSL_GUARDED_BY(mutex1)\n" - " ABSL_GUARDED_BY(mutex2);", + " ABSL_GUARDED_BY(mutex2);", getGoogleStyleWithColumns(40)); verifyFormat("Tttttt f(int a, int b)\n" " ABSL_GUARDED_BY(mutex1)\n" - " ABSL_GUARDED_BY(mutex2);", + " ABSL_GUARDED_BY(mutex2);", getGoogleStyleWithColumns(40)); // * typedefs verifyGoogleFormat("typedef ATTR(X) char x;"); @@ -26267,6 +26295,8 @@ TEST_F(FormatTest, BreakAfterAttributes) { constexpr StringRef Code("[[maybe_unused]] const int i;\n" "[[foo([[]])]] [[maybe_unused]]\n" "int j;\n" + "[[maybe_unused]]\n" + "foo k;\n" "[[nodiscard]] inline int f(int &i);\n" "[[foo([[]])]] [[nodiscard]]\n" "int g(int &i);\n" @@ -26287,6 +26317,7 @@ TEST_F(FormatTest, BreakAfterAttributes) { Style.BreakAfterAttributes = FormatStyle::ABS_Never; verifyFormat("[[maybe_unused]] const int i;\n" "[[foo([[]])]] [[maybe_unused]] int j;\n" + "[[maybe_unused]] foo k;\n" "[[nodiscard]] inline int f(int &i);\n" "[[foo([[]])]] [[nodiscard]] int g(int &i);\n" "[[nodiscard]] inline int f(int &i) {\n" @@ -26304,6 +26335,8 @@ TEST_F(FormatTest, BreakAfterAttributes) { "const int i;\n" "[[foo([[]])]] [[maybe_unused]]\n" "int j;\n" + "[[maybe_unused]]\n" + "foo k;\n" "[[nodiscard]]\n" "inline int f(int &i);\n" "[[foo([[]])]] [[nodiscard]]\n" @@ -26451,6 +26484,19 @@ TEST_F(FormatTest, BreakAfterAttributes) { "{\n" "}", CtorDtorCode, Style); + + verifyFormat("struct Foo {\n" + " [[maybe_unused]]\n" + " void operator+();\n" + "};\n" + "[[nodiscard]]\n" + "Foo &operator-(Foo &);", + Style); + + Style.ReferenceAlignment = FormatStyle::ReferenceAlignmentStyle::RAS_Left; + verifyFormat("[[nodiscard]]\n" + "Foo& operator-(Foo&);", + Style); } TEST_F(FormatTest, InsertNewlineAtEOF) { diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index e185eceb35305799b099a0a87b07b6f3e7e5fe28..3aded8f3726d8ba6614b91de0b3847b0785a8b5c 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -2836,5 +2836,11 @@ TEST_F(FormatTestJS, AlignConsecutiveAssignmentsAndDeclarations) { Style); } +TEST_F(FormatTestJS, DontBreakFieldsAsGoToLabels) { + verifyFormat("export type Params = Config&{\n" + " columns: Column[];\n" + "};"); +} + } // namespace format } // end namespace clang diff --git a/clang/unittests/Format/MatchFilePathTest.cpp b/clang/unittests/Format/MatchFilePathTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55723584ddc800894ec3240548f4688c52bf1001 --- /dev/null +++ b/clang/unittests/Format/MatchFilePathTest.cpp @@ -0,0 +1,169 @@ +//===- unittest/Format/MatchFilePathTest.cpp ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "../../lib/Format/MatchFilePath.h" +#include "gtest/gtest.h" + +namespace clang { +namespace format { +namespace { + +class MatchFilePathTest : public ::testing::Test { +protected: + bool match(llvm::StringRef FilePath, llvm::StringRef Pattern) { + return matchFilePath(Pattern, FilePath); + } +}; + +// Most of the test cases below are from: +// https://github.com/python/cpython/blob/main/Lib/test/test_fnmatch.py + +TEST_F(MatchFilePathTest, Wildcard) { + EXPECT_TRUE(match("abc", "?*?")); + EXPECT_TRUE(match("abc", "???*")); + EXPECT_TRUE(match("abc", "*???")); + EXPECT_TRUE(match("abc", "???")); + EXPECT_TRUE(match("abc", "*")); + EXPECT_TRUE(match("abc", "ab[cd]")); + EXPECT_TRUE(match("abc", "ab[!de]")); + EXPECT_FALSE(match("abc", "ab[de]")); + EXPECT_FALSE(match("a", "??")); + EXPECT_FALSE(match("a", "b")); +} + +TEST_F(MatchFilePathTest, Backslash) { + EXPECT_TRUE(match("a?", R"(a\?)")); + EXPECT_FALSE(match("a\\", R"(a\)")); + EXPECT_TRUE(match("\\", R"([\])")); + EXPECT_TRUE(match("a", R"([!\])")); + EXPECT_FALSE(match("\\", R"([!\])")); +} + +TEST_F(MatchFilePathTest, Newline) { + EXPECT_TRUE(match("foo\nbar", "foo*")); + EXPECT_TRUE(match("foo\nbar\n", "foo*")); + EXPECT_FALSE(match("\nfoo", "foo*")); + EXPECT_TRUE(match("\n", "*")); +} + +TEST_F(MatchFilePathTest, Star) { + EXPECT_TRUE(match(std::string(50, 'a'), "*a*a*a*a*a*a*a*a*a*a")); + EXPECT_FALSE(match((std::string(50, 'a') + 'b'), "*a*a*a*a*a*a*a*a*a*a")); +} + +TEST_F(MatchFilePathTest, CaseSensitive) { + EXPECT_TRUE(match("abc", "abc")); + EXPECT_FALSE(match("AbC", "abc")); + EXPECT_FALSE(match("abc", "AbC")); + EXPECT_TRUE(match("AbC", "AbC")); +} + +TEST_F(MatchFilePathTest, PathSeparators) { + EXPECT_TRUE(match("usr/bin", "usr/bin")); + EXPECT_TRUE(match("usr\\bin", R"(usr\\bin)")); +} + +TEST_F(MatchFilePathTest, NumericEscapeSequence) { + EXPECT_TRUE(match("test", "te*")); + EXPECT_TRUE(match("test\xff", "te*\xff")); + EXPECT_TRUE(match("foo\nbar", "foo*")); +} + +TEST_F(MatchFilePathTest, ValidBrackets) { + EXPECT_TRUE(match("z", "[az]")); + EXPECT_FALSE(match("z", "[!az]")); + EXPECT_TRUE(match("a", "[aa]")); + EXPECT_TRUE(match("^", "[^az]")); + EXPECT_TRUE(match("[", "[[az]")); + EXPECT_FALSE(match("]", "[!]]")); +} + +TEST_F(MatchFilePathTest, InvalidBrackets) { + EXPECT_TRUE(match("[", "[")); + EXPECT_TRUE(match("[]", "[]")); + EXPECT_TRUE(match("[!", "[!")); + EXPECT_TRUE(match("[!]", "[!]")); +} + +TEST_F(MatchFilePathTest, Range) { + EXPECT_TRUE(match("c", "[b-d]")); + EXPECT_FALSE(match("c", "[!b-d]")); + EXPECT_TRUE(match("y", "[b-dx-z]")); + EXPECT_FALSE(match("y", "[!b-dx-z]")); +} + +TEST_F(MatchFilePathTest, Hyphen) { + EXPECT_FALSE(match("#", "[!-#]")); + EXPECT_FALSE(match("-", "[!--.]")); + EXPECT_TRUE(match("_", "[^-`]")); + EXPECT_TRUE(match("]", "[[-^]")); + EXPECT_TRUE(match("]", R"([\-^])")); + EXPECT_TRUE(match("-", "[b-]")); + EXPECT_FALSE(match("-", "[!b-]")); + EXPECT_TRUE(match("-", "[-b]")); + EXPECT_FALSE(match("-", "[!-b]")); + EXPECT_TRUE(match("-", "[-]")); + EXPECT_FALSE(match("-", "[!-]")); +} + +TEST_F(MatchFilePathTest, UpperLELower) { + EXPECT_FALSE(match("c", "[d-b]")); + EXPECT_TRUE(match("c", "[!d-b]")); + EXPECT_TRUE(match("y", "[d-bx-z]")); + EXPECT_FALSE(match("y", "[!d-bx-z]")); + EXPECT_TRUE(match("_", "[d-b^-`]")); + EXPECT_TRUE(match("]", "[d-b[-^]")); + EXPECT_TRUE(match("b", "[b-b]")); +} + +TEST_F(MatchFilePathTest, SlashAndBackslashInBrackets) { + EXPECT_FALSE(match("/", "[/]")); + EXPECT_TRUE(match("\\", R"([\])")); + EXPECT_TRUE(match("[/]", "[/]")); + EXPECT_TRUE(match("\\", R"([\t])")); + EXPECT_TRUE(match("t", R"([\t])")); + EXPECT_FALSE(match("\t", R"([\t])")); +} + +TEST_F(MatchFilePathTest, SlashAndBackslashInRange) { + EXPECT_FALSE(match("a/b", "a[.-0]b")); + EXPECT_TRUE(match("a\\b", "a[Z-^]b")); + EXPECT_FALSE(match("a/b", "a[/-0]b")); + EXPECT_TRUE(match("a[/-0]b", "a[/-0]b")); + EXPECT_FALSE(match("a/b", "a[.-/]b")); + EXPECT_TRUE(match("a[.-/]b", "a[.-/]b")); + EXPECT_TRUE(match("a\\b", R"(a[\-^]b)")); + EXPECT_TRUE(match("a\\b", R"(a[Z-\]b)")); +} + +TEST_F(MatchFilePathTest, Brackets) { + EXPECT_TRUE(match("[", "[[]")); + EXPECT_TRUE(match("&", "[a&&b]")); + EXPECT_TRUE(match("|", "[a||b]")); + EXPECT_TRUE(match("~", "[a~~b]")); + EXPECT_TRUE(match(",", "[a-z+--A-Z]")); + EXPECT_FALSE(match(".", "[a-z--/A-Z]")); +} + +TEST_F(MatchFilePathTest, Path) { + EXPECT_TRUE(match(".clang-format", "*")); + EXPECT_TRUE(match(".git", "*git*")); + EXPECT_TRUE(match(".gitignore", "*git*")); + EXPECT_TRUE(match("foo/bar", "foo*/*bar")); + EXPECT_TRUE(match("foo/bar", "*/*")); + EXPECT_TRUE(match("foo/bar", R"(*foo*\/*bar*)")); + EXPECT_FALSE(match("foo/bar", "foo*")); + EXPECT_FALSE(match("foo/bar", "foo?bar")); + EXPECT_FALSE(match("foo/bar", "foo*bar")); + EXPECT_FALSE(match("foobar", "foo*/*")); + EXPECT_FALSE(match("foo\\", R"(foo*\)")); +} + +} // namespace +} // namespace format +} // namespace clang diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 65b1f0f4b57659870048ca86e2e00d863402afae..2cafc0438ffb46ae93f4fbd1e7e2137de9f5fe49 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -298,6 +298,17 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) { ASSERT_EQ(Tokens.size(), 12u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::identifier, TT_TypeName); EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); + + Tokens = annotate("class Foo {\n" + " void operator<() {}\n" + " Foo &f;\n" + "};"); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[5], tok::less, TT_OverloadedOperator); + EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen); + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace); + EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference); } TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) { @@ -1707,6 +1718,13 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) { ASSERT_EQ(Tokens.size(), 14u) << Tokens; EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionTypeLParen); + + auto Style = getLLVMStyle(); + Style.TypeNames.push_back("time_t"); + Tokens = annotate("int iso_time(time_t);", Style); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[3], tok::identifier, TT_TypeName); } TEST_F(TokenAnnotatorTest, UnderstandsCtorAndDtorDeclNames) { diff --git a/clang/unittests/Frontend/OutputStreamTest.cpp b/clang/unittests/Frontend/OutputStreamTest.cpp index 9cb101ecff8aafe025dd306f4f484396dfc9d609..7d360f661daa30f05a9c9db790dea8ac537ab5cc 100644 --- a/clang/unittests/Frontend/OutputStreamTest.cpp +++ b/clang/unittests/Frontend/OutputStreamTest.cpp @@ -42,7 +42,7 @@ TEST(FrontendOutputTests, TestOutputStream) { bool Success = ExecuteCompilerInvocation(&Compiler); EXPECT_TRUE(Success); EXPECT_TRUE(!IRBuffer.empty()); - EXPECT_TRUE(StringRef(IRBuffer.data()).startswith("BC")); + EXPECT_TRUE(StringRef(IRBuffer.data()).starts_with("BC")); } TEST(FrontendOutputTests, TestVerboseOutputStreamShared) { diff --git a/clang/unittests/Interpreter/CodeCompletionTest.cpp b/clang/unittests/Interpreter/CodeCompletionTest.cpp index 8f5f3545029d08777e51879aa7e46803f96ced1b..873fbda32f057950bba7fe69f25e3641f90bebfc 100644 --- a/clang/unittests/Interpreter/CodeCompletionTest.cpp +++ b/clang/unittests/Interpreter/CodeCompletionTest.cpp @@ -1,7 +1,9 @@ #include "clang/Interpreter/CodeCompletion.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Interpreter/Interpreter.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Sema/Sema.h" #include "llvm/LineEditor/LineEditor.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" @@ -19,7 +21,7 @@ static std::unique_ptr createInterpreter() { } static std::vector runComp(clang::Interpreter &MainInterp, - llvm::StringRef Prefix, + llvm::StringRef Input, llvm::Error &ErrR) { auto CI = CB.CreateCpp(); if (auto Err = CI.takeError()) { @@ -37,66 +39,41 @@ static std::vector runComp(clang::Interpreter &MainInterp, std::vector Results; std::vector Comps; - - codeComplete( - const_cast((*Interp)->getCompilerInstance()), - Prefix, /* Lines */ 1, Prefix.size(), MainInterp.getCompilerInstance(), - Results); + auto *MainCI = (*Interp)->getCompilerInstance(); + auto CC = ReplCodeCompleter(); + CC.codeComplete(MainCI, Input, /* Lines */ 1, Input.size() + 1, + MainInterp.getCompilerInstance(), Results); for (auto Res : Results) - if (Res.find(Prefix) == 0) + if (Res.find(CC.Prefix) == 0) Comps.push_back(Res); - return Comps; } -#ifdef _AIX -TEST(CodeCompletionTest, DISABLED_Sanity) { -#else TEST(CodeCompletionTest, Sanity) { -#endif auto Interp = createInterpreter(); - if (auto R = Interp->ParseAndExecute("int foo = 12;")) { - consumeError(std::move(R)); - return; - } + cantFail(Interp->Parse("int foo = 12;")); auto Err = llvm::Error::success(); auto comps = runComp(*Interp, "f", Err); - EXPECT_EQ((size_t)2, comps.size()); // foo and float - EXPECT_EQ(comps[0], std::string("foo")); + EXPECT_EQ((size_t)2, comps.size()); // float and foo + EXPECT_EQ(comps[0], std::string("float")); + EXPECT_EQ(comps[1], std::string("foo")); EXPECT_EQ((bool)Err, false); } -#ifdef _AIX -TEST(CodeCompletionTest, DISABLED_SanityNoneValid) { -#else TEST(CodeCompletionTest, SanityNoneValid) { -#endif auto Interp = createInterpreter(); - if (auto R = Interp->ParseAndExecute("int foo = 12;")) { - consumeError(std::move(R)); - return; - } + cantFail(Interp->Parse("int foo = 12;")); auto Err = llvm::Error::success(); auto comps = runComp(*Interp, "babanana", Err); EXPECT_EQ((size_t)0, comps.size()); // foo and float EXPECT_EQ((bool)Err, false); } -#ifdef _AIX -TEST(CodeCompletionTest, DISABLED_TwoDecls) { -#else TEST(CodeCompletionTest, TwoDecls) { -#endif auto Interp = createInterpreter(); - if (auto R = Interp->ParseAndExecute("int application = 12;")) { - consumeError(std::move(R)); - return; - } - if (auto R = Interp->ParseAndExecute("int apple = 12;")) { - consumeError(std::move(R)); - return; - } + cantFail(Interp->Parse("int application = 12;")); + cantFail(Interp->Parse("int apple = 12;")); auto Err = llvm::Error::success(); auto comps = runComp(*Interp, "app", Err); EXPECT_EQ((size_t)2, comps.size()); @@ -110,4 +87,154 @@ TEST(CodeCompletionTest, CompFunDeclsNoError) { EXPECT_EQ((bool)Err, false); } +TEST(CodeCompletionTest, TypedDirected) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse("int application = 12;")); + cantFail(Interp->Parse("char apple = '2';")); + cantFail(Interp->Parse("void add(int &SomeInt){}")); + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("add("), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ((bool)Err, false); + } + + cantFail(Interp->Parse("int banana = 42;")); + + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("add("), Err); + EXPECT_EQ((size_t)2, comps.size()); + EXPECT_EQ(comps[0], "application"); + EXPECT_EQ(comps[1], "banana"); + EXPECT_EQ((bool)Err, false); + } + + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("add(b"), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], "banana"); + EXPECT_EQ((bool)Err, false); + } +} + +TEST(CodeCompletionTest, SanityClasses) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse("struct Apple{};")); + cantFail(Interp->Parse("void takeApple(Apple &a1){}")); + cantFail(Interp->Parse("Apple a1;")); + cantFail(Interp->Parse("void takeAppleCopy(Apple a1){}")); + + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, "takeApple(", Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("a1")); + EXPECT_EQ((bool)Err, false); + } + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("takeAppleCopy("), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("a1")); + EXPECT_EQ((bool)Err, false); + } +} + +TEST(CodeCompletionTest, SubClassing) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse("struct Fruit {};")); + cantFail(Interp->Parse("struct Apple : Fruit{};")); + cantFail(Interp->Parse("void takeFruit(Fruit &f){}")); + cantFail(Interp->Parse("Apple a1;")); + cantFail(Interp->Parse("Fruit f1;")); + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("takeFruit("), Err); + EXPECT_EQ((size_t)2, comps.size()); + EXPECT_EQ(comps[0], std::string("a1")); + EXPECT_EQ(comps[1], std::string("f1")); + EXPECT_EQ((bool)Err, false); +} + +TEST(CodeCompletionTest, MultipleArguments) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse("int foo = 42;")); + cantFail(Interp->Parse("char fowl = 'A';")); + cantFail(Interp->Parse("void takeTwo(int &a, char b){}")); + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("takeTwo(foo, "), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("fowl")); + EXPECT_EQ((bool)Err, false); +} + +TEST(CodeCompletionTest, Methods) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse( + "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};")); + cantFail(Interp->Parse("Foo f1;")); + + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("f1."), Err); + EXPECT_EQ((size_t)2, comps.size()); + EXPECT_EQ(comps[0], std::string("add")); + EXPECT_EQ(comps[1], std::string("par")); + EXPECT_EQ((bool)Err, false); +} + +TEST(CodeCompletionTest, MethodsInvocations) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse( + "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};")); + cantFail(Interp->Parse("Foo f1;")); + cantFail(Interp->Parse("int a = 84;")); + + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("f1.add("), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("a")); + EXPECT_EQ((bool)Err, false); +} + +TEST(CodeCompletionTest, NestedInvocations) { + auto Interp = createInterpreter(); + cantFail(Interp->Parse( + "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};")); + cantFail(Interp->Parse("Foo f1;")); + cantFail(Interp->Parse("int a = 84;")); + cantFail(Interp->Parse("int plus(int a, int b) { return a + b; }")); + + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("plus(42, f1.add("), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("a")); + EXPECT_EQ((bool)Err, false); +} + +TEST(CodeCompletionTest, TemplateFunctions) { + auto Interp = createInterpreter(); + cantFail( + Interp->Parse("template T id(T a) { return a;} ")); + cantFail(Interp->Parse("int apple = 84;")); + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("id("), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("apple")); + EXPECT_EQ((bool)Err, false); + } + + cantFail(Interp->Parse( + "template T pickFirst(T a, T b) { return a;} ")); + cantFail(Interp->Parse("char pear = '4';")); + { + auto Err = llvm::Error::success(); + auto comps = runComp(*Interp, std::string("pickFirst(apple, "), Err); + EXPECT_EQ((size_t)1, comps.size()); + EXPECT_EQ(comps[0], std::string("apple")); + EXPECT_EQ((bool)Err, false); + } +} + } // anonymous namespace diff --git a/clang/unittests/Interpreter/IncrementalProcessingTest.cpp b/clang/unittests/Interpreter/IncrementalProcessingTest.cpp index f43b3ddac68f941ee5e7f1c37fdde94527a6d5c7..accdf682896340b4f570f0ef665d664231024202 100644 --- a/clang/unittests/Interpreter/IncrementalProcessingTest.cpp +++ b/clang/unittests/Interpreter/IncrementalProcessingTest.cpp @@ -44,7 +44,7 @@ const char TestProgram2[] = "extern \"C\" int funcForProg2() { return 42; }\n" const Function *getGlobalInit(llvm::Module *M) { for (const auto &Func : *M) - if (Func.hasName() && Func.getName().startswith("_GLOBAL__sub_I_")) + if (Func.hasName() && Func.getName().starts_with("_GLOBAL__sub_I_")) return &Func; return nullptr; diff --git a/clang/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp b/clang/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp index cd78014eae9d61ce53f0c43d76192398c9601f46..aace4b991b5ecabac79f7493d839b005cfc7a8bc 100644 --- a/clang/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp +++ b/clang/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp @@ -15,10 +15,10 @@ namespace ento { TEST(StaticAnalyzerOptions, getRegisteredCheckers) { auto IsDebugChecker = [](StringRef CheckerName) { - return CheckerName.startswith("debug"); + return CheckerName.starts_with("debug"); }; auto IsAlphaChecker = [](StringRef CheckerName) { - return CheckerName.startswith("alpha"); + return CheckerName.starts_with("alpha"); }; const auto &AllCheckers = AnalyzerOptions::getRegisteredCheckers(/*IncludeExperimental=*/true); diff --git a/clang/unittests/StaticAnalyzer/CallEventTest.cpp b/clang/unittests/StaticAnalyzer/CallEventTest.cpp index 5be25d2ada6738e4f13f2ad92fe9f725c8ebf6be..adbfe02a284dc51d44bcc460e39864d529cee4d4 100644 --- a/clang/unittests/StaticAnalyzer/CallEventTest.cpp +++ b/clang/unittests/StaticAnalyzer/CallEventTest.cpp @@ -36,12 +36,7 @@ void reportBug(const CheckerBase *Checker, const CallEvent &Call, } class CXXDeallocatorChecker : public Checker { - std::unique_ptr BT_uninitField; - public: - CXXDeallocatorChecker() - : BT_uninitField(new BugType(this, "CXXDeallocator")) {} - void checkPreCall(const CallEvent &Call, CheckerContext &C) const { const auto *DC = dyn_cast(&Call); if (!DC) { diff --git a/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp b/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp index 69e29b47f925729bec0331f915cc3b4ea842e2b9..51aca42a26b059405449bb27f37010f7fc06b5f9 100644 --- a/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp +++ b/clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp @@ -82,7 +82,7 @@ public: template class StatefulChecker : public Checker { - mutable std::unique_ptr BT; + const BugType BT{this, "error()", categories::SecurityError}; public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const { @@ -102,11 +102,8 @@ public: const ExplodedNode *N = C.generateErrorNode(); if (!N) return; - if (!BT) - BT.reset(new BugType(this->getCheckerName(), "error()", - categories::SecurityError)); auto R = - std::make_unique(*BT, "error() called", N); + std::make_unique(BT, "error() called", N); R->template addVisitor(); C.emitReport(std::move(R)); } diff --git a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp index d5c7a5c9bb8233a6a48409fa04b0f56b59b433d6..cd46efc8ad762c50c05c602b780cd817c083a714 100644 --- a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp +++ b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp @@ -89,8 +89,7 @@ TEST(RegisterCustomCheckers, CheckLocationIncDec) { class CheckerRegistrationOrderPrinter : public Checker> { - std::unique_ptr BT = - std::make_unique(this, "Registration order"); + const BugType BT{this, "Registration order"}; public: void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const { @@ -104,7 +103,7 @@ public: .printEnabledCheckerList(OS); // Strip a newline off. auto R = - std::make_unique(*BT, OS.str().drop_back(1), N); + std::make_unique(BT, OS.str().drop_back(1), N); C.emitReport(std::move(R)); } }; @@ -125,8 +124,6 @@ void addCheckerRegistrationOrderPrinter(CheckerRegistry &Registry) { #define UNITTEST_CHECKER(CHECKER_NAME, DIAG_MSG) \ class CHECKER_NAME : public Checker> { \ - std::unique_ptr BT = std::make_unique(this, DIAG_MSG); \ - \ public: \ void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {} \ }; \ diff --git a/clang/unittests/Tooling/HeaderIncludesTest.cpp b/clang/unittests/Tooling/HeaderIncludesTest.cpp index 256aa825554c5073ba9f0d8d4c83d13297a9cee8..929156a11d0d9a23b5cbe3547d79d3f1fc826e17 100644 --- a/clang/unittests/Tooling/HeaderIncludesTest.cpp +++ b/clang/unittests/Tooling/HeaderIncludesTest.cpp @@ -23,9 +23,9 @@ protected: std::string insert(llvm::StringRef Code, llvm::StringRef Header, IncludeDirective Directive = IncludeDirective::Include) { HeaderIncludes Includes(FileName, Code, Style); - assert(Header.startswith("\"") || Header.startswith("<")); - auto R = - Includes.insert(Header.trim("\"<>"), Header.startswith("<"), Directive); + assert(Header.starts_with("\"") || Header.starts_with("<")); + auto R = Includes.insert(Header.trim("\"<>"), Header.starts_with("<"), + Directive); if (!R) return std::string(Code); auto Result = applyAllReplacements(Code, Replacements(*R)); @@ -35,8 +35,9 @@ protected: std::string remove(llvm::StringRef Code, llvm::StringRef Header) { HeaderIncludes Includes(FileName, Code, Style); - assert(Header.startswith("\"") || Header.startswith("<")); - auto Replaces = Includes.remove(Header.trim("\"<>"), Header.startswith("<")); + assert(Header.starts_with("\"") || Header.starts_with("<")); + auto Replaces = + Includes.remove(Header.trim("\"<>"), Header.starts_with("<")); auto Result = applyAllReplacements(Code, Replaces); EXPECT_TRUE(static_cast(Result)); return *Result; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp index 594b299b54369402cda6c46defe4d466deed9aee..6a8d91672f1d936aaddc29561b5c4c7201cf93f0 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp @@ -86,6 +86,25 @@ TEST(RecursiveASTVisitor, Concepts) { EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed); EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); EXPECT_EQ(1, Visitor.ConceptReferencesVisited); + + Visitor = {}; + llvm::StringRef Code = + R"cpp( +template concept True = false; +template struct Foo {}; + +template + requires requires { requires True; } +struct Foo {}; + +template requires True +struct Foo {}; + )cpp"; + EXPECT_TRUE(Visitor.runOver(Code, ConceptVisitor::Lang_CXX2a)); + // Check that the concept references from the partial specializations are + // visited. + EXPECT_EQ(2, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(2, Visitor.ConceptReferencesVisited); } struct VisitDeclOnlyOnce : ExpectedLocationVisitor { diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp index 354af292a541081146a33fd82034180554316b2d..2e3da2cd2a7013577f485c6e49642de2136d10bb 100644 --- a/clang/unittests/Tooling/ToolingTest.cpp +++ b/clang/unittests/Tooling/ToolingTest.cpp @@ -197,8 +197,8 @@ TEST(ToolInvocation, TestMapVirtualFile) { TEST(ToolInvocation, TestVirtualModulesCompilation) { // FIXME: Currently, this only tests that we don't exit with an error if a - // mapped module.map is found on the include path. In the future, expand this - // test to run a full modules enabled compilation, so we make sure we can + // mapped module.modulemap is found on the include path. In the future, expand + // this test to run a full modules enabled compilation, so we make sure we can // rerun modules compilations with a virtual file system. llvm::IntrusiveRefCntPtr OverlayFileSystem( new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem())); @@ -218,9 +218,9 @@ TEST(ToolInvocation, TestVirtualModulesCompilation) { "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("#include \n")); InMemoryFileSystem->addFile("def/abc", 0, llvm::MemoryBuffer::getMemBuffer("\n")); - // Add a module.map file in the include directory of our header, so we trigger - // the module.map header search logic. - InMemoryFileSystem->addFile("def/module.map", 0, + // Add a module.modulemap file in the include directory of our header, so we + // trigger the module.modulemap header search logic. + InMemoryFileSystem->addFile("def/module.modulemap", 0, llvm::MemoryBuffer::getMemBuffer("\n")); EXPECT_TRUE(Invocation.run()); } diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp index 60904bc3baf89e1aae7970deed12c06dac69335b..87075a46d75187b0d8a1e2c3fa4be877a93f00ae 100644 --- a/clang/unittests/libclang/LibclangTest.cpp +++ b/clang/unittests/libclang/LibclangTest.cpp @@ -451,8 +451,8 @@ public: const auto Filename = llvm::sys::path::filename(File->path()); EXPECT_EQ(Filename.size(), std::strlen("preamble-%%%%%%.pch")); - EXPECT_TRUE(Filename.startswith("preamble-")); - EXPECT_TRUE(Filename.endswith(".pch")); + EXPECT_TRUE(Filename.starts_with("preamble-")); + EXPECT_TRUE(Filename.ends_with(".pch")); const auto Status = File->status(); ASSERT_TRUE(Status); @@ -659,7 +659,7 @@ TEST_F(LibclangReparseTest, FileName) { clang_disposeString(cxname); cxname = clang_File_tryGetRealPathName(cxf); - ASSERT_TRUE(llvm::StringRef(clang_getCString(cxname)).endswith("main.cpp")); + ASSERT_TRUE(llvm::StringRef(clang_getCString(cxname)).ends_with("main.cpp")); clang_disposeString(cxname); } diff --git a/clang/utils/TableGen/ASTTableGen.cpp b/clang/utils/TableGen/ASTTableGen.cpp index 60f563d9a1ffc8b8eed2ff1d81251805a1604e19..54288ff6a03be3b7203bec275d167d35d95f7f39 100644 --- a/clang/utils/TableGen/ASTTableGen.cpp +++ b/clang/utils/TableGen/ASTTableGen.cpp @@ -33,7 +33,7 @@ llvm::StringRef clang::tblgen::HasProperties::getName() const { static StringRef removeExpectedNodeNameSuffix(Record *node, StringRef suffix) { StringRef nodeName = node->getName(); - if (!nodeName.endswith(suffix)) { + if (!nodeName.ends_with(suffix)) { PrintFatalError(node->getLoc(), Twine("name of node doesn't end in ") + suffix); } diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp index fae889d68346c33c8ad22c8ad67eb63843722562..f0bd0865c1c8b56fac081ea70f4e4a433c90583e 100644 --- a/clang/utils/TableGen/MveEmitter.cpp +++ b/clang/utils/TableGen/MveEmitter.cpp @@ -882,7 +882,7 @@ public: } else if (V->varnameUsed()) { std::string Type = V->typeName(); OS << V->typeName(); - if (!StringRef(Type).endswith("*")) + if (!StringRef(Type).ends_with("*")) OS << " "; OS << V->varname() << " = "; } @@ -1680,7 +1680,7 @@ void EmitterBase::EmitBuiltinCG(raw_ostream &OS) { for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i) { StringRef Type = MG.ParamTypes[i]; OS << " " << Type; - if (!Type.endswith("*")) + if (!Type.ends_with("*")) OS << " "; OS << " Param" << utostr(i) << ";\n"; } @@ -1833,7 +1833,7 @@ void MveEmitter::EmitHeader(raw_ostream &OS) { // prototype. std::string RetTypeName = Int.returnType()->cName(); - if (!StringRef(RetTypeName).endswith("*")) + if (!StringRef(RetTypeName).ends_with("*")) RetTypeName += " "; std::vector ArgTypeNames; @@ -2078,7 +2078,7 @@ void CdeEmitter::EmitHeader(raw_ostream &OS) { // Make strings for the types involved in the function's // prototype. std::string RetTypeName = Int.returnType()->cName(); - if (!StringRef(RetTypeName).endswith("*")) + if (!StringRef(RetTypeName).ends_with("*")) RetTypeName += " "; std::vector ArgTypeNames; diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp index 4b112972a1ec98195a91983a2040a8e4196a17a9..53334016c180a12dfb00c7c7265ee974a20595e0 100644 --- a/clang/utils/TableGen/NeonEmitter.cpp +++ b/clang/utils/TableGen/NeonEmitter.cpp @@ -550,6 +550,8 @@ class NeonEmitter { void createIntrinsic(Record *R, SmallVectorImpl &Out); void genBuiltinsDef(raw_ostream &OS, SmallVectorImpl &Defs); + void genStreamingSVECompatibleList(raw_ostream &OS, + SmallVectorImpl &Defs); void genOverloadTypeCheckCode(raw_ostream &OS, SmallVectorImpl &Defs); void genIntrinsicRangeCheckCode(raw_ostream &OS, @@ -593,6 +595,8 @@ public: // Emit arm_bf16.h.inc void runBF16(raw_ostream &o); + void runVectorTypes(raw_ostream &o); + // Emit all the __builtin prototypes used in arm_neon.h, arm_fp16.h and // arm_bf16.h void runHeader(raw_ostream &o); @@ -2039,6 +2043,30 @@ void NeonEmitter::genBuiltinsDef(raw_ostream &OS, OS << "#endif\n\n"; } +void NeonEmitter::genStreamingSVECompatibleList( + raw_ostream &OS, SmallVectorImpl &Defs) { + OS << "#ifdef GET_NEON_STREAMING_COMPAT_FLAG\n"; + + std::set Emitted; + for (auto *Def : Defs) { + // If the def has a body (that is, it has Operation DAGs), it won't call + // __builtin_neon_* so we don't need to generate a definition for it. + if (Def->hasBody()) + continue; + + std::string Name = Def->getMangledName(); + if (Emitted.find(Name) != Emitted.end()) + continue; + + // FIXME: We should make exceptions here for some NEON builtins that are + // permitted in streaming mode. + OS << "case NEON::BI__builtin_neon_" << Name + << ": BuiltinType = ArmNonStreaming; break;\n"; + Emitted.insert(Name); + } + OS << "#endif\n\n"; +} + /// Generate the ARM and AArch64 overloaded type checking code for /// SemaChecking.cpp, checking for unique builtin declarations. void NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS, @@ -2222,6 +2250,8 @@ void NeonEmitter::runHeader(raw_ostream &OS) { // Generate ARM overloaded type checking code for SemaChecking.cpp genOverloadTypeCheckCode(OS, Defs); + genStreamingSVECompatibleList(OS, Defs); + // Generate ARM range checking code for shift/lane immediates. genIntrinsicRangeCheckCode(OS, Defs); } @@ -2355,13 +2385,7 @@ void NeonEmitter::run(raw_ostream &OS) { OS << "#include \n"; - // Emit NEON-specific scalar typedefs. - OS << "typedef float float32_t;\n"; - OS << "typedef __fp16 float16_t;\n"; - - OS << "#ifdef __aarch64__\n"; - OS << "typedef double float64_t;\n"; - OS << "#endif\n\n"; + OS << "#include \n"; // For now, signedness of polynomial types depends on target OS << "#ifdef __aarch64__\n"; @@ -2374,10 +2398,7 @@ void NeonEmitter::run(raw_ostream &OS) { OS << "typedef int16_t poly16_t;\n"; OS << "typedef int64_t poly64_t;\n"; OS << "#endif\n"; - - emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl", OS); - - emitNeonTypeDefs("bQb", OS); + emitNeonTypeDefs("PcQPcPsQPsPlQPl", OS); OS << "#define __ai static __inline__ __attribute__((__always_inline__, " "__nodebug__))\n\n"; @@ -2546,6 +2567,38 @@ void NeonEmitter::runFP16(raw_ostream &OS) { OS << "#endif /* __ARM_FP16_H */\n"; } +void NeonEmitter::runVectorTypes(raw_ostream &OS) { + OS << "/*===---- arm_vector_types - ARM vector type " + "------===\n" + " *\n" + " *\n" + " * Part of the LLVM Project, under the Apache License v2.0 with LLVM " + "Exceptions.\n" + " * See https://llvm.org/LICENSE.txt for license information.\n" + " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n" + " *\n" + " *===-----------------------------------------------------------------" + "------===\n" + " */\n\n"; + OS << "#if !defined(__ARM_NEON_H) && !defined(__ARM_SVE_H)\n"; + OS << "#error \"This file should not be used standalone. Please include" + " arm_neon.h or arm_sve.h instead\"\n\n"; + OS << "#endif\n"; + OS << "#ifndef __ARM_NEON_TYPES_H\n"; + OS << "#define __ARM_NEON_TYPES_H\n"; + OS << "typedef float float32_t;\n"; + OS << "typedef __fp16 float16_t;\n"; + + OS << "#ifdef __aarch64__\n"; + OS << "typedef double float64_t;\n"; + OS << "#endif\n\n"; + + emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQd", OS); + + emitNeonTypeDefs("bQb", OS); + OS << "#endif // __ARM_NEON_TYPES_H\n"; +} + void NeonEmitter::runBF16(raw_ostream &OS) { OS << "/*===---- arm_bf16.h - ARM BF16 intrinsics " "-----------------------------------===\n" @@ -2640,6 +2693,10 @@ void clang::EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) { NeonEmitter(Records).runHeader(OS); } +void clang::EmitVectorTypes(RecordKeeper &Records, raw_ostream &OS) { + NeonEmitter(Records).runVectorTypes(OS); +} + void clang::EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) { llvm_unreachable("Neon test generation no longer implemented!"); } diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 1fb41805a0473dd538c9777aa8af121d36c1f1da..d570bcae8d8636a333a1af5b0f226fa0f805dff1 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -46,7 +46,7 @@ struct SemaRecord { unsigned Log2LMULMask; // Required extensions for this intrinsic. - unsigned RequiredExtensions; + uint32_t RequiredExtensions; // Prototype for this intrinsic. SmallVector Prototype; @@ -151,7 +151,7 @@ static BasicType ParseBasicType(char c) { case 'd': return BasicType::Float64; break; - case 'b': + case 'y': return BasicType::BFloat16; break; default: @@ -653,24 +653,26 @@ void RVVEmitter::createRVVIntrinsics( SR.RequiredExtensions = 0; for (auto RequiredFeature : RequiredFeatures) { - RVVRequire RequireExt = StringSwitch(RequiredFeature) - .Case("RV64", RVV_REQ_RV64) - .Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh) - .Case("Xsfvcp", RVV_REQ_Xsfvcp) - .Case("Xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf) - .Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq) - .Case("Xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod) - .Case("Xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq) - .Case("Zvbb", RVV_REQ_Zvbb) - .Case("Zvbc", RVV_REQ_Zvbc) - .Case("Zvkb", RVV_REQ_Zvkb) - .Case("Zvkg", RVV_REQ_Zvkg) - .Case("Zvkned", RVV_REQ_Zvkned) - .Case("Zvknha", RVV_REQ_Zvknha) - .Case("Zvknhb", RVV_REQ_Zvknhb) - .Case("Zvksed", RVV_REQ_Zvksed) - .Case("Zvksh", RVV_REQ_Zvksh) - .Default(RVV_REQ_None); + RVVRequire RequireExt = + StringSwitch(RequiredFeature) + .Case("RV64", RVV_REQ_RV64) + .Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh) + .Case("Xsfvcp", RVV_REQ_Xsfvcp) + .Case("Xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf) + .Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq) + .Case("Xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod) + .Case("Xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq) + .Case("Zvbb", RVV_REQ_Zvbb) + .Case("Zvbc", RVV_REQ_Zvbc) + .Case("Zvkb", RVV_REQ_Zvkb) + .Case("Zvkg", RVV_REQ_Zvkg) + .Case("Zvkned", RVV_REQ_Zvkned) + .Case("Zvknha", RVV_REQ_Zvknha) + .Case("Zvknhb", RVV_REQ_Zvknhb) + .Case("Zvksed", RVV_REQ_Zvksed) + .Case("Zvksh", RVV_REQ_Zvksh) + .Case("Experimental", RVV_REQ_Experimental) + .Default(RVV_REQ_None); assert(RequireExt != RVV_REQ_None && "Unrecognized required feature?"); SR.RequiredExtensions |= RequireExt; } diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index b8a1fb4bab0f499d74cc1e0c2cf9128c32d8754d..6c302da106a2cf52dc98a6663f7bbcef649146d2 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -97,6 +97,7 @@ public: bool isScalar() const { return NumVectors == 0; } bool isVector() const { return NumVectors > 0; } bool isScalableVector() const { return isVector() && IsScalable; } + bool isFixedLengthVector() const { return isVector() && !IsScalable; } bool isChar() const { return ElementBitwidth == 8; } bool isVoid() const { return Void & !Pointer; } bool isDefault() const { return DefaultType; } @@ -378,9 +379,15 @@ public: /// Emit all the information needed to map builtin -> LLVM IR intrinsic. void createSMECodeGenMap(raw_ostream &o); + /// Create a table for a builtin's requirement for PSTATE.SM. + void createStreamingAttrs(raw_ostream &o, ACLEKind Kind); + /// Emit all the range checks for the immediates. void createSMERangeChecks(raw_ostream &o); + /// Create a table for a builtin's requirement for PSTATE.ZA. + void createBuiltinZAState(raw_ostream &OS); + /// Create intrinsic and add it to \p Out void createIntrinsic(Record *R, SmallVectorImpl> &Out); @@ -466,7 +473,8 @@ std::string SVEType::builtin_str() const { return S; } - assert(isScalableVector() && "Unsupported type"); + if (isFixedLengthVector()) + return "V" + utostr(getNumElements() * NumVectors) + S; return "q" + utostr(getNumElements() * NumVectors) + S; } @@ -499,7 +507,7 @@ std::string SVEType::str() const { if (!isScalarPredicate() && !isPredicateVector() && !isSvcount()) S += utostr(ElementBitwidth); - if (!isScalableVector() && isVector()) + if (isFixedLengthVector()) S += "x" + utostr(getNumElements()); if (NumVectors > 1) S += "x" + utostr(NumVectors); @@ -610,6 +618,11 @@ void SVEType::applyModifier(char Mod) { Bitwidth = 16; ElementBitwidth = 1; break; + case '{': + IsScalable = false; + Bitwidth = 128; + NumVectors = 1; + break; case 's': case 'a': Bitwidth = ElementBitwidth; @@ -1286,6 +1299,7 @@ void SVEEmitter::createHeader(raw_ostream &OS) { OS << "typedef __SVBfloat16_t svbfloat16_t;\n"; OS << "#include \n"; + OS << "#include \n"; OS << "typedef __SVFloat32_t svfloat32_t;\n"; OS << "typedef __SVFloat64_t svfloat64_t;\n"; @@ -1589,6 +1603,25 @@ void SVEEmitter::createSMEHeader(raw_ostream &OS) { OS << "extern \"C\" {\n"; OS << "#endif\n\n"; + OS << "void __arm_za_disable(void) __arm_streaming_compatible;\n\n"; + + OS << "__ai bool __arm_has_sme(void) __arm_streaming_compatible {\n"; + OS << " uint64_t x0, x1;\n"; + OS << " __builtin_arm_get_sme_state(&x0, &x1);\n"; + OS << " return x0 & (1ULL << 63);\n"; + OS << "}\n\n"; + + OS << "__ai bool __arm_in_streaming_mode(void) __arm_streaming_compatible " + "{\n"; + OS << " uint64_t x0, x1;\n"; + OS << " __builtin_arm_get_sme_state(&x0, &x1);\n"; + OS << " return x0 & 1;\n"; + OS << "}\n\n"; + + OS << "__ai __attribute__((target(\"sme\"))) void svundef_za(void) " + "__arm_streaming_compatible __arm_shared_za " + "{ }\n\n"; + createCoreHeaderIntrinsics(OS, *this, ACLEKind::SME); OS << "#ifdef __cplusplus\n"; @@ -1694,6 +1727,76 @@ void SVEEmitter::createSMERangeChecks(raw_ostream &OS) { OS << "#endif\n\n"; } +void SVEEmitter::createBuiltinZAState(raw_ostream &OS) { + std::vector RV = Records.getAllDerivedDefinitions("Inst"); + SmallVector, 128> Defs; + for (auto *R : RV) + createIntrinsic(R, Defs); + + std::map> DefsZAState; + + uint64_t IsSharedZAFlag = getEnumValueForFlag("IsSharedZA"); + for (auto &Def : Defs) { + bool HasZAState = Def->isFlagSet(IsSharedZAFlag); + DefsZAState[HasZAState].insert(Def->getMangledName()); + } + + OS << "#ifdef GET_SME_BUILTIN_HAS_ZA_STATE\n"; + + for (auto HasZA : {true, false}) { + auto Names = DefsZAState[HasZA]; + for (auto Name : Names) + OS << "case SME::BI__builtin_sme_" << Name << ":\n"; + OS << " return " << (HasZA ? "true" : "false") << ";\n"; + } + OS << "#endif\n\n"; +} + +void SVEEmitter::createStreamingAttrs(raw_ostream &OS, ACLEKind Kind) { + std::vector RV = Records.getAllDerivedDefinitions("Inst"); + SmallVector, 128> Defs; + for (auto *R : RV) + createIntrinsic(R, Defs); + + StringRef ExtensionKind; + switch (Kind) { + case ACLEKind::SME: + ExtensionKind = "SME"; + break; + case ACLEKind::SVE: + ExtensionKind = "SVE"; + break; + } + + OS << "#ifdef GET_" << ExtensionKind << "_STREAMING_ATTRS\n"; + + llvm::StringMap> StreamingMap; + + uint64_t IsStreamingFlag = getEnumValueForFlag("IsStreaming"); + uint64_t IsStreamingCompatibleFlag = + getEnumValueForFlag("IsStreamingCompatible"); + for (auto &Def : Defs) { + if (Def->isFlagSet(IsStreamingFlag)) + StreamingMap["ArmStreaming"].insert(Def->getMangledName()); + else if (Def->isFlagSet(IsStreamingCompatibleFlag)) + StreamingMap["ArmStreamingCompatible"].insert(Def->getMangledName()); + else + StreamingMap["ArmNonStreaming"].insert(Def->getMangledName()); + } + + for (auto BuiltinType : StreamingMap.keys()) { + for (auto Name : StreamingMap[BuiltinType]) { + OS << "case " << ExtensionKind << "::BI__builtin_" + << ExtensionKind.lower() << "_"; + OS << Name << ":\n"; + } + OS << " BuiltinType = " << BuiltinType << ";\n"; + OS << " break;\n"; + } + + OS << "#endif\n\n"; +} + namespace clang { void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createHeader(OS); @@ -1715,6 +1818,10 @@ void EmitSveTypeFlags(RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createTypeFlags(OS); } +void EmitSveStreamingAttrs(RecordKeeper &Records, raw_ostream &OS) { + SVEEmitter(Records).createStreamingAttrs(OS, ACLEKind::SVE); +} + void EmitSmeHeader(RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createSMEHeader(OS); } @@ -1730,4 +1837,12 @@ void EmitSmeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) { void EmitSmeRangeChecks(RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createSMERangeChecks(OS); } + +void EmitSmeStreamingAttrs(RecordKeeper &Records, raw_ostream &OS) { + SVEEmitter(Records).createStreamingAttrs(OS, ACLEKind::SME); +} + +void EmitSmeBuiltinZAState(RecordKeeper &Records, raw_ostream &OS) { + SVEEmitter(Records).createBuiltinZAState(OS); +} } // End namespace clang diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp index 7efb6c731d3e5ee2c1f202f556d1c6eee62e4f31..c1f2ca15b595c0cc32b7e9628efc7717d19431db 100644 --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -73,6 +73,7 @@ enum ActionType { GenArmNeon, GenArmFP16, GenArmBF16, + GenArmVectorType, GenArmNeonSema, GenArmNeonTest, GenArmMveHeader, @@ -85,10 +86,13 @@ enum ActionType { GenArmSveBuiltinCG, GenArmSveTypeFlags, GenArmSveRangeChecks, + GenArmSveStreamingAttrs, GenArmSmeHeader, GenArmSmeBuiltins, GenArmSmeBuiltinCG, GenArmSmeRangeChecks, + GenArmSmeStreamingAttrs, + GenArmSmeBuiltinZAState, GenArmCdeHeader, GenArmCdeBuiltinDef, GenArmCdeBuiltinSema, @@ -229,6 +233,8 @@ cl::opt Action( clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"), clEnumValN(GenArmFP16, "gen-arm-fp16", "Generate arm_fp16.h for clang"), clEnumValN(GenArmBF16, "gen-arm-bf16", "Generate arm_bf16.h for clang"), + clEnumValN(GenArmVectorType, "gen-arm-vector-type", + "Generate arm_vector_types.h for clang"), clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", "Generate ARM NEON sema support for clang"), clEnumValN(GenArmNeonTest, "gen-arm-neon-test", @@ -243,6 +249,8 @@ cl::opt Action( "Generate arm_sve_typeflags.inc for clang"), clEnumValN(GenArmSveRangeChecks, "gen-arm-sve-sema-rangechecks", "Generate arm_sve_sema_rangechecks.inc for clang"), + clEnumValN(GenArmSveStreamingAttrs, "gen-arm-sve-streaming-attrs", + "Generate arm_sve_streaming_attrs.inc for clang"), clEnumValN(GenArmSmeHeader, "gen-arm-sme-header", "Generate arm_sme.h for clang"), clEnumValN(GenArmSmeBuiltins, "gen-arm-sme-builtins", @@ -251,6 +259,10 @@ cl::opt Action( "Generate arm_sme_builtin_cg_map.inc for clang"), clEnumValN(GenArmSmeRangeChecks, "gen-arm-sme-sema-rangechecks", "Generate arm_sme_sema_rangechecks.inc for clang"), + clEnumValN(GenArmSmeStreamingAttrs, "gen-arm-sme-streaming-attrs", + "Generate arm_sme_streaming_attrs.inc for clang"), + clEnumValN(GenArmSmeBuiltinZAState, "gen-arm-sme-builtin-za-state", + "Generate arm_sme_builtins_za_state.inc for clang"), clEnumValN(GenArmMveHeader, "gen-arm-mve-header", "Generate arm_mve.h for clang"), clEnumValN(GenArmMveBuiltinDef, "gen-arm-mve-builtin-def", @@ -449,6 +461,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenArmFP16: EmitFP16(Records, OS); break; + case GenArmVectorType: + EmitVectorTypes(Records, OS); + break; case GenArmBF16: EmitBF16(Records, OS); break; @@ -488,6 +503,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenArmSveRangeChecks: EmitSveRangeChecks(Records, OS); break; + case GenArmSveStreamingAttrs: + EmitSveStreamingAttrs(Records, OS); + break; case GenArmSmeHeader: EmitSmeHeader(Records, OS); break; @@ -500,6 +518,12 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenArmSmeRangeChecks: EmitSmeRangeChecks(Records, OS); break; + case GenArmSmeStreamingAttrs: + EmitSmeStreamingAttrs(Records, OS); + break; + case GenArmSmeBuiltinZAState: + EmitSmeBuiltinZAState(Records, OS); + break; case GenArmCdeHeader: EmitCdeHeader(Records, OS); break; diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h index d8f447069376bca352b74dbd55df337573078562..35f2f04c1e818df001a5fc15a01ce9deb4649b52 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -97,6 +97,7 @@ void EmitNeon(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitFP16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitBF16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitNeonSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitVectorTypes(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitNeonTest(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); @@ -104,11 +105,14 @@ void EmitSveBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveTypeFlags(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveRangeChecks(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitSveStreamingAttrs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSmeHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSmeBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSmeBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSmeRangeChecks(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitSmeStreamingAttrs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitSmeBuiltinZAState(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitMveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitMveBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); diff --git a/clang/www/analyzer/faq.html b/clang/www/analyzer/faq.html index 72ca27eb8c36b907e3306d4d3040634bf3a9d551..156d383db2f2343d26d8190b1348eff9f614dba7 100644 --- a/clang/www/analyzer/faq.html +++ b/clang/www/analyzer/faq.html @@ -195,12 +195,45 @@ int foo(int length) {

Q: How can I suppress a specific analyzer warning?

-

There is currently no solid mechanism for suppressing an analyzer warning, -although this is currently being investigated. When you encounter an analyzer -bug/false positive, check if it's one of the issues discussed above or if the -analyzer annotations can -resolve the issue. Second, please report it to -help us improve user experience. As the last resort, consider using __clang_analyzer__ macro +

When you encounter an analyzer bug/false positive, check if it's one of the +issues discussed above or if the analyzer +annotations can +resolve the issue by helping the static analyzer understand the code better. +Second, please report it to help us improve +user experience.

+ +

Sometimes there's really no "good" way to eliminate the issue. In such cases +you can "silence" it directly by annotating the problematic line of code with +the help of Clang attribute 'suppress': + +

+int foo() {
+  int *x = nullptr;
+  ...
+  [[clang::suppress]] {
+    // all warnings in this scope are suppressed
+    int y = *x;
+  }
+
+  // null pointer dereference warning suppressed on the next line
+  [[clang::suppress]]
+  return *x
+}
+
+int bar(bool coin_flip) {
+  // suppress all memory leak warnings about this allocation
+  [[clang::suppress]]
+  int *result = (int *)malloc(sizeof(int));
+
+  if (coin_flip)
+    return 0;      // including this leak path
+
+  return *result;  // as well as this leak path
+}
+
+ + +

You can also consider using __clang_analyzer__ macro described below.

Q: How can I selectively exclude code the analyzer examines?

diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index 4d9b68a3cc25bf16a9c3589dd86abd3953de2ee2..7aca0abc637d4e05b9db1abbce8142366b662d9f 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -670,6 +670,10 @@ macro(add_custom_libcxx name prefix) get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}") + if(CMAKE_VERBOSE_MAKEFILE) + set(verbose -DCMAKE_VERBOSE_MAKEFILE=ON) + endif() + ExternalProject_Add(${name} DEPENDS ${name}-clobber ${LIBCXX_DEPS} PREFIX ${CMAKE_CURRENT_BINARY_DIR}/${name} @@ -677,6 +681,7 @@ macro(add_custom_libcxx name prefix) BINARY_DIR ${prefix} CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} ${compiler_args} + ${verbose} -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS} -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS} -DCMAKE_BUILD_TYPE=Release diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index a8e078f1ebc98887438e9444b3f77545a7a9d40b..2dccd4954b253782a30914d182d5bfa93d2438fb 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -450,11 +450,17 @@ if(APPLE) set(TSAN_SUPPORTED_OS osx) set(XRAY_SUPPORTED_OS osx) set(FUZZER_SUPPORTED_OS osx) - set(ORC_SUPPORTED_OS osx) + set(ORC_SUPPORTED_OS) set(UBSAN_SUPPORTED_OS osx) set(LSAN_SUPPORTED_OS osx) set(STATS_SUPPORTED_OS osx) + # FIXME: Support a general COMPILER_RT_ENABLE_OSX to match other platforms. + set(ORC_ENABLE_OSX 1 CACHE BOOL "Whether to build the orc runtime library for osx") + if(ORC_ENABLE_OSX) + set(ORC_SUPPORTED_OS osx) + endif() + # Note: In order to target x86_64h on OS X the minimum deployment target must # be 10.8 or higher. set(DEFAULT_SANITIZER_MIN_OSX_VERSION 10.10) diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc index 44a449800923fdc4fd9a60fc3b46fc64becde66f..f5de23ff4b94d98344099c71e3bf2b9e372c28ed 100644 --- a/compiler-rt/include/profile/InstrProfData.inc +++ b/compiler-rt/include/profile/InstrProfData.inc @@ -295,6 +295,12 @@ INSTR_PROF_SECT_ENTRY(IPSK_covfun, \ INSTR_PROF_SECT_ENTRY(IPSK_orderfile, \ INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COFF), "__DATA,") +INSTR_PROF_SECT_ENTRY(IPSK_covdata, \ + INSTR_PROF_QUOTE(INSTR_PROF_COVDATA_COMMON), \ + INSTR_PROF_COVDATA_COFF, "__LLVM_COV,") +INSTR_PROF_SECT_ENTRY(IPSK_covname, \ + INSTR_PROF_QUOTE(INSTR_PROF_COVNAME_COMMON), \ + INSTR_PROF_COVNAME_COFF, "__LLVM_COV,") #undef INSTR_PROF_SECT_ENTRY #endif @@ -701,6 +707,8 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, #define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds #define INSTR_PROF_COVMAP_COMMON __llvm_covmap #define INSTR_PROF_COVFUN_COMMON __llvm_covfun +#define INSTR_PROF_COVDATA_COMMON __llvm_covdata +#define INSTR_PROF_COVNAME_COMMON __llvm_covnames #define INSTR_PROF_ORDERFILE_COMMON __llvm_orderfile /* Windows section names. Because these section names contain dollar characters, * they must be quoted. @@ -713,6 +721,11 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, #define INSTR_PROF_VNODES_COFF ".lprfnd$M" #define INSTR_PROF_COVMAP_COFF ".lcovmap$M" #define INSTR_PROF_COVFUN_COFF ".lcovfun$M" +/* Since cov data and cov names sections are not allocated, we don't need to + * access them at runtime. + */ +#define INSTR_PROF_COVDATA_COFF ".lcovd" +#define INSTR_PROF_COVNAME_COFF ".lcovn" #define INSTR_PROF_ORDERFILE_COFF ".lorderfile$M" #ifdef _WIN32 @@ -729,6 +742,8 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, #define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF #define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF #define INSTR_PROF_COVFUN_SECT_NAME INSTR_PROF_COVFUN_COFF +#define INSTR_PROF_COVDATA_SECT_NAME INSTR_PROF_COVDATA_COFF +#define INSTR_PROF_COVNAME_SECT_NAME INSTR_PROF_COVNAME_COFF #define INSTR_PROF_ORDERFILE_SECT_NAME INSTR_PROF_ORDERFILE_COFF #else /* Runtime section names and name strings. */ @@ -744,6 +759,8 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, #define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON) #define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON) #define INSTR_PROF_COVFUN_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVFUN_COMMON) +#define INSTR_PROF_COVDATA_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVDATA_COMMON) +#define INSTR_PROF_COVNAME_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVNAME_COMMON) /* Order file instrumentation. */ #define INSTR_PROF_ORDERFILE_SECT_NAME \ INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON) diff --git a/compiler-rt/include/sanitizer/hwasan_interface.h b/compiler-rt/include/sanitizer/hwasan_interface.h index abe310c0666948300c2c4a8f352ec60d89456870..407f488a24a617f67822b57b1e1b623f0c53426b 100644 --- a/compiler-rt/include/sanitizer/hwasan_interface.h +++ b/compiler-rt/include/sanitizer/hwasan_interface.h @@ -44,6 +44,10 @@ void SANITIZER_CDECL __hwasan_tag_memory(const volatile void *p, void *SANITIZER_CDECL __hwasan_tag_pointer(const volatile void *p, unsigned char tag); +/// Get tag from the pointer. +unsigned char SANITIZER_CDECL +__hwasan_get_tag_from_pointer(const volatile void *p); + // Set memory tag from the current SP address to the given address to zero. // This is meant to annotate longjmp and other non-local jumps. // This function needs to know the (almost) exact destination frame address; diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt index f993521d3ca88be0ffbb21839aa2744d2fb55065..f83ae82d42935a106cceead6dcba83a83fa642dd 100644 --- a/compiler-rt/lib/asan/CMakeLists.txt +++ b/compiler-rt/lib/asan/CMakeLists.txt @@ -71,7 +71,6 @@ SET(ASAN_HEADERS asan_interface.inc asan_interface_internal.h asan_internal.h - asan_lock.h asan_mapping.h asan_poisoning.h asan_premap_shadow.h diff --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp index 2b15504123bee7c95908ffb7dc0f99290d469327..12625e9d75833de9537c29cb366aabb5be30e773 100644 --- a/compiler-rt/lib/asan/asan_fuchsia.cpp +++ b/compiler-rt/lib/asan/asan_fuchsia.cpp @@ -240,6 +240,8 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { // So this doesn't install any atexit hook like on other platforms. void InstallAtExitCheckLeaks() {} +void InstallAtForkHandler() {} + } // namespace __asan namespace __lsan { diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index 5b97e77882cd67482e16947545f0290b81490d02..2944ebe213b5d56991a2d954c7871e6242bf1209 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -126,6 +126,7 @@ void *AsanDlSymNext(const char *sym); bool HandleDlopenInit(); void InstallAtExitCheckLeaks(); +void InstallAtForkHandler(); #define ASAN_ON_ERROR() \ if (&__asan_on_error) \ diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp index e19b4479aaf345531ef984a456090ff8bb194a9a..37d3bad1b1ec6256d08b21f2227a73f7f238528f 100644 --- a/compiler-rt/lib/asan/asan_linux.cpp +++ b/compiler-rt/lib/asan/asan_linux.cpp @@ -33,7 +33,6 @@ # include "asan_premap_shadow.h" # include "asan_thread.h" # include "sanitizer_common/sanitizer_flags.h" -# include "sanitizer_common/sanitizer_freebsd.h" # include "sanitizer_common/sanitizer_hash.h" # include "sanitizer_common/sanitizer_libc.h" # include "sanitizer_common/sanitizer_procmaps.h" @@ -59,13 +58,6 @@ extern Elf_Dyn _DYNAMIC; extern ElfW(Dyn) _DYNAMIC[]; # endif -// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in -// 32-bit mode. -# if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \ - __FreeBSD_version <= 902001 // v9.2 -# define ucontext_t xucontext_t -# endif - typedef enum { ASAN_RT_VERSION_UNDEFINED = 0, ASAN_RT_VERSION_DYNAMIC, @@ -148,6 +140,11 @@ static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, internal_strncmp(info->dlpi_name, "linux-", sizeof("linux-") - 1) == 0) return 0; # endif +# if SANITIZER_FREEBSD + // Ignore vDSO. + if (internal_strcmp(info->dlpi_name, "[vdso]") == 0) + return 0; +# endif *name = info->dlpi_name; return 1; diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp index 17280129c758bc5e9fca4aa693e7f49e299ba1ce..b5b1ced8ac5edae85822fce06b31282ad46cc8d8 100644 --- a/compiler-rt/lib/asan/asan_new_delete.cpp +++ b/compiler-rt/lib/asan/asan_new_delete.cpp @@ -48,15 +48,6 @@ COMMENT_EXPORT("??_V@YAXPAX@Z") // operator delete[] using namespace __asan; -// FreeBSD prior v9.2 have wrong definition of 'size_t'. -// http://svnweb.freebsd.org/base?view=revision&revision=232261 -#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 -#include -#if __FreeBSD_version <= 902001 // v9.2 -#define size_t unsigned -#endif // __FreeBSD_version -#endif // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 - // This code has issues on OSX. // See https://github.com/google/sanitizers/issues/131. diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp index e1f66641617cc14b4336ccc25d012ff1194d5772..76564538bd5d7786e6bd46809ce65257ecd19978 100644 --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -146,7 +146,38 @@ void PlatformTSDDtor(void *tsd) { # endif AsanThread::TSDDtor(tsd); } -#endif +# endif + +static void BeforeFork() { + if (CAN_SANITIZE_LEAKS) { + __lsan::LockGlobal(); + } + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and lock the + // stuff we need. + __lsan::LockThreads(); + __lsan::LockAllocator(); + StackDepotLockBeforeFork(); +} + +static void AfterFork(bool fork_child) { + StackDepotUnlockAfterFork(fork_child); + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and unlock + // the stuff we need. + __lsan::UnlockAllocator(); + __lsan::UnlockThreads(); + if (CAN_SANITIZE_LEAKS) { + __lsan::UnlockGlobal(); + } +} + +void InstallAtForkHandler() { +# if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE + return; // FIXME: Implement FutexWait. +# endif + pthread_atfork( + &BeforeFork, []() { AfterFork(/* fork_child= */ false); }, + []() { AfterFork(/* fork_child= */ true); }); +} void InstallAtExitCheckLeaks() { if (CAN_SANITIZE_LEAKS) { diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp index 04ecd20821fa6deea8a38fcceb85bf8e49fa0435..a61deed7382b0291c212ef4c3a0c7fe5875d8cfd 100644 --- a/compiler-rt/lib/asan/asan_rtl.cpp +++ b/compiler-rt/lib/asan/asan_rtl.cpp @@ -71,16 +71,16 @@ static void CheckUnwind() { } // -------------------------- Globals --------------------- {{{1 -static int asan_inited = 0; -static int asan_init_is_running = 0; +static StaticSpinMutex asan_inited_mutex; +static atomic_uint8_t asan_inited = {0}; -static void SetAsanInited() { asan_inited = 1; } - -static void SetAsanInitIsRunning(u32 val) { asan_init_is_running = val; } - -bool AsanInited() { return asan_inited == 1; } +static void SetAsanInited() { + atomic_store(&asan_inited, 1, memory_order_release); +} -static bool AsanInitIsRunning() { return asan_init_is_running == 1; } +bool AsanInited() { + return atomic_load(&asan_inited, memory_order_acquire) == 1; +} bool replace_intrin_cached; @@ -390,12 +390,10 @@ void PrintAddressSpaceLayout() { kHighShadowBeg > kMidMemEnd); } -static void AsanInitInternal() { +static bool AsanInitInternal() { if (LIKELY(AsanInited())) - return; + return true; SanitizerToolName = "AddressSanitizer"; - CHECK(!AsanInitIsRunning() && "ASan init calls itself!"); - SetAsanInitIsRunning(1); CacheBinaryName(); @@ -408,9 +406,8 @@ static void AsanInitInternal() { // Stop performing init at this point if we are being loaded via // dlopen() and the platform supports it. if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) { - SetAsanInitIsRunning(0); VReport(1, "AddressSanitizer init is being performed for dlopen().\n"); - return; + return false; } AsanCheckIncompatibleRT(); @@ -471,7 +468,6 @@ static void AsanInitInternal() { // should be set to 1 prior to initializing the threads. replace_intrin_cached = flags()->replace_intrin; SetAsanInited(); - SetAsanInitIsRunning(0); if (flags()->atexit) Atexit(asan_atexit); @@ -497,6 +493,8 @@ static void AsanInitInternal() { InstallAtExitCheckLeaks(); } + InstallAtForkHandler(); + #if CAN_SANITIZE_UB __ubsan::InitAsPlugin(); #endif @@ -515,22 +513,27 @@ static void AsanInitInternal() { VReport(1, "AddressSanitizer Init done\n"); WaitForDebugger(flags()->sleep_after_init, "after init"); + + return true; } // Initialize as requested from some part of ASan runtime library (interceptors, // allocator, etc). void AsanInitFromRtl() { - CHECK(!AsanInitIsRunning()); - if (UNLIKELY(!AsanInited())) - AsanInitInternal(); + if (LIKELY(AsanInited())) + return; + SpinMutexLock lock(&asan_inited_mutex); + AsanInitInternal(); } bool TryAsanInitFromRtl() { - if (UNLIKELY(AsanInitIsRunning())) + if (LIKELY(AsanInited())) + return true; + if (!asan_inited_mutex.TryLock()) return false; - if (UNLIKELY(!AsanInited())) - AsanInitInternal(); - return true; + bool result = AsanInitInternal(); + asan_inited_mutex.Unlock(); + return result; } #if ASAN_DYNAMIC @@ -603,7 +606,7 @@ static void UnpoisonFakeStack() { using namespace __asan; void NOINLINE __asan_handle_no_return() { - if (AsanInitIsRunning()) + if (UNLIKELY(!AsanInited())) return; if (!PlatformUnpoisonStacks()) @@ -633,7 +636,7 @@ void NOINLINE __asan_set_death_callback(void (*callback)(void)) { // We use this call as a trigger to wake up ASan from deactivated state. void __asan_init() { AsanActivate(); - AsanInitInternal(); + AsanInitFromRtl(); } void __asan_version_mismatch_check() { diff --git a/compiler-rt/lib/asan/asan_rtl_x86_64.S b/compiler-rt/lib/asan/asan_rtl_x86_64.S index 0b7363018f425f020a0204191715ed4a3fcda769..9c5289856d8ae67736a2bf4086316be580b0378a 100644 --- a/compiler-rt/lib/asan/asan_rtl_x86_64.S +++ b/compiler-rt/lib/asan/asan_rtl_x86_64.S @@ -27,7 +27,12 @@ FNAME(reg, op, s, i): ;\ #define ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, s) \ mov %##reg,%r10 ;\ shr $0x3,%r10 ;\ + .if ASAN_SHADOW_OFFSET_CONST < 0x80000000 ;\ movsbl ASAN_SHADOW_OFFSET_CONST(%r10),%r10d ;\ + .else ;\ + movabsq $ASAN_SHADOW_OFFSET_CONST,%r11 ;\ + movsbl (%r10,%r11),%r10d ;\ + .endif ;\ test %r10d,%r10d ;\ jne CLABEL(reg, op, s, add) ;\ RLABEL(reg, op, s, add): ;\ @@ -84,7 +89,12 @@ ENDF #define ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, s, c) \ mov %##reg,%r10 ;\ shr $0x3,%r10 ;\ + .if ASAN_SHADOW_OFFSET_CONST < 0x80000000 ;\ ##c $0x0,ASAN_SHADOW_OFFSET_CONST(%r10) ;\ + .else ;\ + movabsq $ASAN_SHADOW_OFFSET_CONST,%r11 ;\ + ##c $0x0,(%r10,%r11) ;\ + .endif ;\ jne FLABEL(reg, op, s, add) ;\ retq ;\ diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp index d5a30f471e2b0d45de18820b983a15d662dfbb56..f16ce677618e4fe58d895f94fc8fb2a1eeeb93f0 100644 --- a/compiler-rt/lib/asan/asan_win.cpp +++ b/compiler-rt/lib/asan/asan_win.cpp @@ -203,6 +203,8 @@ void InitializePlatformInterceptors() { void InstallAtExitCheckLeaks() {} +void InstallAtForkHandler() {} + void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { UNIMPLEMENTED(); } diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index ea72c595a9b807c9a396bf6d9ddd07f7e5948a4c..e5b52db175d960f5ae8ba3e558bfadd5cee95a83 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -271,7 +271,7 @@ endif() # These files are used on 32-bit and 64-bit x86. set(x86_ARCH_SOURCES - cpu_model.c + cpu_model/x86.c ) if (NOT MSVC) @@ -556,7 +556,7 @@ endif() set(aarch64_SOURCES ${GENERIC_TF_SOURCES} ${GENERIC_SOURCES} - cpu_model.c + cpu_model/aarch64.c aarch64/fp_mode.c ) diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c new file mode 100644 index 0000000000000000000000000000000000000000..44e1cf49d1e9274f29d351737cab506454e2b65b --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c @@ -0,0 +1,151 @@ +//===-- cpu_model/aarch64.c - Support for __cpu_model builtin ----*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is based on LLVM's lib/Support/Host.cpp. +// It implements __aarch64_have_lse_atomics, __aarch64_cpu_features for +// AArch64. +// +//===----------------------------------------------------------------------===// + +#include "cpu_model.h" + +#if !defined(__aarch64__) +#error This file is intended only for aarch64-based targets +#endif + +#if __has_include() +#include +#else +typedef struct __ifunc_arg_t { + unsigned long _size; + unsigned long _hwcap; + unsigned long _hwcap2; +} __ifunc_arg_t; +#endif // __has_include() + +// LSE support detection for out-of-line atomics +// using HWCAP and Auxiliary vector +_Bool __aarch64_have_lse_atomics + __attribute__((visibility("hidden"), nocommon)) = false; + +#if defined(__FreeBSD__) +// clang-format off: should not reorder sys/auxv.h alphabetically +#include +// clang-format on +#include "aarch64/hwcap.inc" +#include "aarch64/lse_atomics/freebsd.inc" +#elif defined(__Fuchsia__) +#include "aarch64/hwcap.inc" +#include "aarch64/lse_atomics/fuchsia.inc" +#elif defined(__ANDROID__) +#include "aarch64/hwcap.inc" +#include "aarch64/lse_atomics/android.inc" +#elif __has_include() +#include "aarch64/hwcap.inc" +#include "aarch64/lse_atomics/sysauxv.inc" +#else +// When unimplemented, we leave __aarch64_have_lse_atomics initialized to false. +#endif + +#if !defined(DISABLE_AARCH64_FMV) +// CPUFeatures must correspond to the same AArch64 features in +// AArch64TargetParser.h +enum CPUFeatures { + FEAT_RNG, + FEAT_FLAGM, + FEAT_FLAGM2, + FEAT_FP16FML, + FEAT_DOTPROD, + FEAT_SM4, + FEAT_RDM, + FEAT_LSE, + FEAT_FP, + FEAT_SIMD, + FEAT_CRC, + FEAT_SHA1, + FEAT_SHA2, + FEAT_SHA3, + FEAT_AES, + FEAT_PMULL, + FEAT_FP16, + FEAT_DIT, + FEAT_DPB, + FEAT_DPB2, + FEAT_JSCVT, + FEAT_FCMA, + FEAT_RCPC, + FEAT_RCPC2, + FEAT_FRINTTS, + FEAT_DGH, + FEAT_I8MM, + FEAT_BF16, + FEAT_EBF16, + FEAT_RPRES, + FEAT_SVE, + FEAT_SVE_BF16, + FEAT_SVE_EBF16, + FEAT_SVE_I8MM, + FEAT_SVE_F32MM, + FEAT_SVE_F64MM, + FEAT_SVE2, + FEAT_SVE_AES, + FEAT_SVE_PMULL128, + FEAT_SVE_BITPERM, + FEAT_SVE_SHA3, + FEAT_SVE_SM4, + FEAT_SME, + FEAT_MEMTAG, + FEAT_MEMTAG2, + FEAT_MEMTAG3, + FEAT_SB, + FEAT_PREDRES, + FEAT_SSBS, + FEAT_SSBS2, + FEAT_BTI, + FEAT_LS64, + FEAT_LS64_V, + FEAT_LS64_ACCDATA, + FEAT_WFXT, + FEAT_SME_F64, + FEAT_SME_I64, + FEAT_SME2, + FEAT_RCPC3, + FEAT_MAX, + FEAT_EXT = 62, // Reserved to indicate presence of additional features field + // in __aarch64_cpu_features + FEAT_INIT // Used as flag of features initialization completion +}; + +// Architecture features used +// in Function Multi Versioning +struct { + unsigned long long features; + // As features grows new fields could be added +} __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon)); + +// The formatter wants to re-order these includes, but doing so is incorrect: +// clang-format off +#if defined(__APPLE__) +#include "aarch64/fmv/apple.inc" +#elif defined(__FreeBSD__) +#include "aarch64/fmv/mrs.inc" +#include "aarch64/fmv/freebsd.inc" +#elif defined(__Fuchsia__) +#include "aarch64/fmv/fuchsia.inc" +#elif defined(__ANDROID__) +#include "aarch64/fmv/mrs.inc" +#include "aarch64/fmv/android.inc" +#elif __has_include() +#include "aarch64/fmv/mrs.inc" +#include "aarch64/fmv/sysauxv.inc" +#else +#include "aarch64/fmv/unimplemented.inc" +#endif +// clang-format on + +#endif // !defined(DISABLE_AARCH64_FMV) diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc new file mode 100644 index 0000000000000000000000000000000000000000..f711431489cc770db07fa226adaba63e20168a8a --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc @@ -0,0 +1,36 @@ +void __init_cpu_features_resolver(unsigned long hwcap, + const __ifunc_arg_t *arg) { + if (__aarch64_cpu_features.features) + return; + + // ifunc resolvers don't have hwcaps in arguments on Android API lower + // than 30. If so, set feature detection done and keep all CPU features + // unsupported (zeros). To detect this case in runtime we check existence + // of memfd_create function from Standard C library which was introduced in + // Android API 30. + int memfd_create(const char *, unsigned int) __attribute__((weak)); + if (!memfd_create) + return; + + __init_cpu_features_constructor(hwcap, arg); +} + +void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) { + // CPU features already initialized. + if (__aarch64_cpu_features.features) + return; + + // Don't set any CPU features, + // detection could be wrong on Exynos 9810. + if (__isExynos9810()) + return; + + unsigned long hwcap = getauxval(AT_HWCAP); + unsigned long hwcap2 = getauxval(AT_HWCAP2); + + __ifunc_arg_t arg; + arg._size = sizeof(__ifunc_arg_t); + arg._hwcap = hwcap; + arg._hwcap2 = hwcap2; + __init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg); +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc new file mode 100644 index 0000000000000000000000000000000000000000..79d4ac70bd1b6dfa1d0cbb2385692d84ac9e9369 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc @@ -0,0 +1,69 @@ +#include +#if TARGET_OS_OSX || TARGET_OS_IPHONE +#include +#include + +static bool isKnownAndSupported(const char *name) { + int32_t val = 0; + size_t size = sizeof(val); + if (sysctlbyname(name, &val, &size, NULL, 0)) + return false; + return val; +} + +void __init_cpu_features_resolver(void) { + // On Darwin platforms, this may be called concurrently by multiple threads + // because the resolvers that use it are called lazily at runtime (unlike on + // ELF platforms, where IFuncs are resolved serially at load time). This + // function's effect on __aarch64_cpu_features should be idempotent, but even + // so we need dispatch_once to resolve the race condition. Dispatch is + // available through libSystem, which we need anyway for the sysctl, so this + // does not add a new dependency. + + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics + static struct { + const char *sysctl_name; + enum CPUFeatures feature; + } features[] = { + {"hw.optional.arm.FEAT_FlagM", FEAT_FLAGM}, + {"hw.optional.arm.FEAT_FlagM2", FEAT_FLAGM2}, + {"hw.optional.arm.FEAT_FHM", FEAT_FP16FML}, + {"hw.optional.arm.FEAT_DotProd", FEAT_DOTPROD}, + {"hw.optional.arm.FEAT_RDM", FEAT_RDM}, + {"hw.optional.arm.FEAT_LSE", FEAT_LSE}, + {"hw.optional.floatingpoint", FEAT_FP}, + {"hw.optional.AdvSIMD", FEAT_SIMD}, + {"hw.optional.armv8_crc32", FEAT_CRC}, + {"hw.optional.arm.FEAT_SHA1", FEAT_SHA1}, + {"hw.optional.arm.FEAT_SHA256", FEAT_SHA2}, + {"hw.optional.arm.FEAT_SHA3", FEAT_SHA3}, + {"hw.optional.arm.FEAT_AES", FEAT_AES}, + {"hw.optional.arm.FEAT_PMULL", FEAT_PMULL}, + {"hw.optional.arm.FEAT_FP16", FEAT_FP16}, + {"hw.optional.arm.FEAT_DIT", FEAT_DIT}, + {"hw.optional.arm.FEAT_DPB", FEAT_DPB}, + {"hw.optional.arm.FEAT_DPB2", FEAT_DPB2}, + {"hw.optional.arm.FEAT_JSCVT", FEAT_JSCVT}, + {"hw.optional.arm.FEAT_FCMA", FEAT_FCMA}, + {"hw.optional.arm.FEAT_LRCPC", FEAT_RCPC}, + {"hw.optional.arm.FEAT_LRCPC2", FEAT_RCPC2}, + {"hw.optional.arm.FEAT_FRINTTS", FEAT_FRINTTS}, + {"hw.optional.arm.FEAT_I8MM", FEAT_I8MM}, + {"hw.optional.arm.FEAT_BF16", FEAT_BF16}, + {"hw.optional.arm.FEAT_SB", FEAT_SB}, + {"hw.optional.arm.FEAT_SPECRES", FEAT_PREDRES}, + {"hw.optional.arm.FEAT_SSBS", FEAT_SSBS2}, + {"hw.optional.arm.FEAT_BTI", FEAT_BTI}, + }; + + for (size_t I = 0, E = sizeof(features) / sizeof(features[0]); I != E; ++I) + if (isKnownAndSupported(features[I].sysctl_name)) + __aarch64_cpu_features.features |= (1ULL << features[I].feature); + + __aarch64_cpu_features.features |= (1ULL << FEAT_INIT); + }); +} + +#endif // TARGET_OS_OSX || TARGET_OS_IPHONE diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc new file mode 100644 index 0000000000000000000000000000000000000000..793adef44b93659d5c148922e6d148bc7ed1d138 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc @@ -0,0 +1,27 @@ +void __init_cpu_features_resolver(unsigned long hwcap, + const __ifunc_arg_t *arg) { + if (__aarch64_cpu_features.features) + return; + + __init_cpu_features_constructor(hwcap, arg); +} + +void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) { + unsigned long hwcap = 0; + unsigned long hwcap2 = 0; + // CPU features already initialized. + if (__aarch64_cpu_features.features) + return; + + int res = 0; + res = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); + res |= elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2); + if (res) + return; + + __ifunc_arg_t arg; + arg._size = sizeof(__ifunc_arg_t); + arg._hwcap = hwcap; + arg._hwcap2 = hwcap2; + __init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg); +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fuchsia.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fuchsia.inc new file mode 100644 index 0000000000000000000000000000000000000000..d8e0280f4041678b830a999f0321240565241634 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fuchsia.inc @@ -0,0 +1,51 @@ +#include +#include + +void __init_cpu_features_resolver() { + if (__aarch64_cpu_features.features) + return; + + // This ensures the vDSO is a direct link-time dependency of anything that + // needs this initializer code. +#pragma comment(lib, "zircon") + uint32_t features; + zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features); + if (status != ZX_OK) + return; + +#define setCPUFeature(cpu_feature) \ + __aarch64_cpu_features.features |= 1ULL << cpu_feature + + if (features & ZX_ARM64_FEATURE_ISA_FP) + setCPUFeature(FEAT_FP); + if (features & ZX_ARM64_FEATURE_ISA_ASIMD) + setCPUFeature(FEAT_SIMD); + if (features & ZX_ARM64_FEATURE_ISA_AES) + setCPUFeature(FEAT_AES); + if (features & ZX_ARM64_FEATURE_ISA_PMULL) + setCPUFeature(FEAT_PMULL); + if (features & ZX_ARM64_FEATURE_ISA_SHA1) + setCPUFeature(FEAT_SHA1); + if (features & ZX_ARM64_FEATURE_ISA_SHA256) + setCPUFeature(FEAT_SHA2); + if (features & ZX_ARM64_FEATURE_ISA_CRC32) + setCPUFeature(FEAT_CRC); + if (features & ZX_ARM64_FEATURE_ISA_RDM) + setCPUFeature(FEAT_RDM); + if (features & ZX_ARM64_FEATURE_ISA_SHA3) + setCPUFeature(FEAT_SHA3); + if (features & ZX_ARM64_FEATURE_ISA_SM4) + setCPUFeature(FEAT_SM4); + if (features & ZX_ARM64_FEATURE_ISA_DP) + setCPUFeature(FEAT_DOTPROD); + if (features & ZX_ARM64_FEATURE_ISA_FHM) + setCPUFeature(FEAT_FP16FML); + if (features & ZX_ARM64_FEATURE_ISA_SHA512) + setCPUFeature(FEAT_SHA3); + if (features & ZX_ARM64_FEATURE_ISA_I8MM) + setCPUFeature(FEAT_I8MM); + if (features & ZX_ARM64_FEATURE_ISA_SVE) + setCPUFeature(FEAT_SVE); + + setCPUFeature(FEAT_INIT); +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc new file mode 100644 index 0000000000000000000000000000000000000000..2f712f41f497924903fb055b985259a86a82b339 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc @@ -0,0 +1,196 @@ +#if __has_include() +#include +#define HAVE_SYS_AUXV_H +#endif + + + +static void __init_cpu_features_constructor(unsigned long hwcap, + const __ifunc_arg_t *arg) { +#define setCPUFeature(F) __aarch64_cpu_features.features |= 1ULL << F +#define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr)) +#define extractBits(val, start, number) \ + (val & ((1ULL << number) - 1ULL) << start) >> start + unsigned long hwcap2 = 0; + if (hwcap & _IFUNC_ARG_HWCAP) + hwcap2 = arg->_hwcap2; + if (hwcap & HWCAP_CRC32) + setCPUFeature(FEAT_CRC); + if (hwcap & HWCAP_PMULL) + setCPUFeature(FEAT_PMULL); + if (hwcap & HWCAP_FLAGM) + setCPUFeature(FEAT_FLAGM); + if (hwcap2 & HWCAP2_FLAGM2) { + setCPUFeature(FEAT_FLAGM); + setCPUFeature(FEAT_FLAGM2); + } + if (hwcap & HWCAP_SM3 && hwcap & HWCAP_SM4) + setCPUFeature(FEAT_SM4); + if (hwcap & HWCAP_ASIMDDP) + setCPUFeature(FEAT_DOTPROD); + if (hwcap & HWCAP_ASIMDFHM) + setCPUFeature(FEAT_FP16FML); + if (hwcap & HWCAP_FPHP) { + setCPUFeature(FEAT_FP16); + setCPUFeature(FEAT_FP); + } + if (hwcap & HWCAP_DIT) + setCPUFeature(FEAT_DIT); + if (hwcap & HWCAP_ASIMDRDM) + setCPUFeature(FEAT_RDM); + if (hwcap & HWCAP_ILRCPC) + setCPUFeature(FEAT_RCPC2); + if (hwcap & HWCAP_AES) + setCPUFeature(FEAT_AES); + if (hwcap & HWCAP_SHA1) + setCPUFeature(FEAT_SHA1); + if (hwcap & HWCAP_SHA2) + setCPUFeature(FEAT_SHA2); + if (hwcap & HWCAP_JSCVT) + setCPUFeature(FEAT_JSCVT); + if (hwcap & HWCAP_FCMA) + setCPUFeature(FEAT_FCMA); + if (hwcap & HWCAP_SB) + setCPUFeature(FEAT_SB); + if (hwcap & HWCAP_SSBS) + setCPUFeature(FEAT_SSBS2); + if (hwcap2 & HWCAP2_MTE) { + setCPUFeature(FEAT_MEMTAG); + setCPUFeature(FEAT_MEMTAG2); + } + if (hwcap2 & HWCAP2_MTE3) { + setCPUFeature(FEAT_MEMTAG); + setCPUFeature(FEAT_MEMTAG2); + setCPUFeature(FEAT_MEMTAG3); + } + if (hwcap2 & HWCAP2_SVEAES) + setCPUFeature(FEAT_SVE_AES); + if (hwcap2 & HWCAP2_SVEPMULL) { + setCPUFeature(FEAT_SVE_AES); + setCPUFeature(FEAT_SVE_PMULL128); + } + if (hwcap2 & HWCAP2_SVEBITPERM) + setCPUFeature(FEAT_SVE_BITPERM); + if (hwcap2 & HWCAP2_SVESHA3) + setCPUFeature(FEAT_SVE_SHA3); + if (hwcap2 & HWCAP2_SVESM4) + setCPUFeature(FEAT_SVE_SM4); + if (hwcap2 & HWCAP2_DCPODP) + setCPUFeature(FEAT_DPB2); + if (hwcap & HWCAP_ATOMICS) + setCPUFeature(FEAT_LSE); + if (hwcap2 & HWCAP2_RNG) + setCPUFeature(FEAT_RNG); + if (hwcap2 & HWCAP2_I8MM) + setCPUFeature(FEAT_I8MM); + if (hwcap2 & HWCAP2_EBF16) + setCPUFeature(FEAT_EBF16); + if (hwcap2 & HWCAP2_SVE_EBF16) + setCPUFeature(FEAT_SVE_EBF16); + if (hwcap2 & HWCAP2_DGH) + setCPUFeature(FEAT_DGH); + if (hwcap2 & HWCAP2_FRINT) + setCPUFeature(FEAT_FRINTTS); + if (hwcap2 & HWCAP2_SVEI8MM) + setCPUFeature(FEAT_SVE_I8MM); + if (hwcap2 & HWCAP2_SVEF32MM) + setCPUFeature(FEAT_SVE_F32MM); + if (hwcap2 & HWCAP2_SVEF64MM) + setCPUFeature(FEAT_SVE_F64MM); + if (hwcap2 & HWCAP2_BTI) + setCPUFeature(FEAT_BTI); + if (hwcap2 & HWCAP2_RPRES) + setCPUFeature(FEAT_RPRES); + if (hwcap2 & HWCAP2_WFXT) + setCPUFeature(FEAT_WFXT); + if (hwcap2 & HWCAP2_SME) + setCPUFeature(FEAT_SME); + if (hwcap2 & HWCAP2_SME_I16I64) + setCPUFeature(FEAT_SME_I64); + if (hwcap2 & HWCAP2_SME_F64F64) + setCPUFeature(FEAT_SME_F64); + if (hwcap & HWCAP_CPUID) { + unsigned long ftr; + getCPUFeature(ID_AA64PFR1_EL1, ftr); + // ID_AA64PFR1_EL1.MTE >= 0b0001 + if (extractBits(ftr, 8, 4) >= 0x1) + setCPUFeature(FEAT_MEMTAG); + // ID_AA64PFR1_EL1.SSBS == 0b0001 + if (extractBits(ftr, 4, 4) == 0x1) + setCPUFeature(FEAT_SSBS); + // ID_AA64PFR1_EL1.SME == 0b0010 + if (extractBits(ftr, 24, 4) == 0x2) + setCPUFeature(FEAT_SME2); + getCPUFeature(ID_AA64PFR0_EL1, ftr); + // ID_AA64PFR0_EL1.FP != 0b1111 + if (extractBits(ftr, 16, 4) != 0xF) { + setCPUFeature(FEAT_FP); + // ID_AA64PFR0_EL1.AdvSIMD has the same value as ID_AA64PFR0_EL1.FP + setCPUFeature(FEAT_SIMD); + } + // ID_AA64PFR0_EL1.SVE != 0b0000 + if (extractBits(ftr, 32, 4) != 0x0) { + // get ID_AA64ZFR0_EL1, that name supported + // if sve enabled only + getCPUFeature(S3_0_C0_C4_4, ftr); + // ID_AA64ZFR0_EL1.SVEver == 0b0000 + if (extractBits(ftr, 0, 4) == 0x0) + setCPUFeature(FEAT_SVE); + // ID_AA64ZFR0_EL1.SVEver == 0b0001 + if (extractBits(ftr, 0, 4) == 0x1) + setCPUFeature(FEAT_SVE2); + // ID_AA64ZFR0_EL1.BF16 != 0b0000 + if (extractBits(ftr, 20, 4) != 0x0) + setCPUFeature(FEAT_SVE_BF16); + } + getCPUFeature(ID_AA64ISAR0_EL1, ftr); + // ID_AA64ISAR0_EL1.SHA3 != 0b0000 + if (extractBits(ftr, 32, 4) != 0x0) + setCPUFeature(FEAT_SHA3); + getCPUFeature(ID_AA64ISAR1_EL1, ftr); + // ID_AA64ISAR1_EL1.DPB >= 0b0001 + if (extractBits(ftr, 0, 4) >= 0x1) + setCPUFeature(FEAT_DPB); + // ID_AA64ISAR1_EL1.LRCPC != 0b0000 + if (extractBits(ftr, 20, 4) != 0x0) + setCPUFeature(FEAT_RCPC); + // ID_AA64ISAR1_EL1.LRCPC == 0b0011 + if (extractBits(ftr, 20, 4) == 0x3) + setCPUFeature(FEAT_RCPC3); + // ID_AA64ISAR1_EL1.SPECRES == 0b0001 + if (extractBits(ftr, 40, 4) == 0x2) + setCPUFeature(FEAT_PREDRES); + // ID_AA64ISAR1_EL1.BF16 != 0b0000 + if (extractBits(ftr, 44, 4) != 0x0) + setCPUFeature(FEAT_BF16); + // ID_AA64ISAR1_EL1.LS64 >= 0b0001 + if (extractBits(ftr, 60, 4) >= 0x1) + setCPUFeature(FEAT_LS64); + // ID_AA64ISAR1_EL1.LS64 >= 0b0010 + if (extractBits(ftr, 60, 4) >= 0x2) + setCPUFeature(FEAT_LS64_V); + // ID_AA64ISAR1_EL1.LS64 >= 0b0011 + if (extractBits(ftr, 60, 4) >= 0x3) + setCPUFeature(FEAT_LS64_ACCDATA); + } else { + // Set some features in case of no CPUID support + if (hwcap & (HWCAP_FP | HWCAP_FPHP)) { + setCPUFeature(FEAT_FP); + // FP and AdvSIMD fields have the same value + setCPUFeature(FEAT_SIMD); + } + if (hwcap & HWCAP_DCPOP || hwcap2 & HWCAP2_DCPODP) + setCPUFeature(FEAT_DPB); + if (hwcap & HWCAP_LRCPC || hwcap & HWCAP_ILRCPC) + setCPUFeature(FEAT_RCPC); + if (hwcap2 & HWCAP2_BF16 || hwcap2 & HWCAP2_EBF16) + setCPUFeature(FEAT_BF16); + if (hwcap2 & HWCAP2_SVEBF16) + setCPUFeature(FEAT_SVE_BF16); + if (hwcap2 & HWCAP2_SVE2 && hwcap & HWCAP_SVE) + setCPUFeature(FEAT_SVE2); + if (hwcap & HWCAP_SHA3) + setCPUFeature(FEAT_SHA3); + } + setCPUFeature(FEAT_INIT); +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/sysauxv.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/sysauxv.inc new file mode 100644 index 0000000000000000000000000000000000000000..fb5722c4306fd88a7476641071014ecf2ddb31aa --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/sysauxv.inc @@ -0,0 +1,21 @@ +void __init_cpu_features_resolver(unsigned long hwcap, + const __ifunc_arg_t *arg) { + if (__aarch64_cpu_features.features) + return; + __init_cpu_features_constructor(hwcap, arg); +} + +void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) { + // CPU features already initialized. + if (__aarch64_cpu_features.features) + return; + + unsigned long hwcap = getauxval(AT_HWCAP); + unsigned long hwcap2 = getauxval(AT_HWCAP2); + + __ifunc_arg_t arg; + arg._size = sizeof(__ifunc_arg_t); + arg._hwcap = hwcap; + arg._hwcap2 = hwcap2; + __init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg); +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/unimplemented.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/unimplemented.inc new file mode 100644 index 0000000000000000000000000000000000000000..dc34624807b748f4316ff5f1b8a0fbd5dabafb2d --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/unimplemented.inc @@ -0,0 +1,8 @@ +// On platforms that have not implemented this yet, we provide an implementation +// that does not claim support for any features by leaving +// __aarch64_cpu_features.features initialized to 0. + +void __init_cpu_features_resolver(unsigned long hwcap, + const __ifunc_arg_t *arg) {} + +void __init_cpu_features(void) {} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc new file mode 100644 index 0000000000000000000000000000000000000000..328d9c4140b9c626f8c743b00467d0bef1b47dea --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc @@ -0,0 +1,180 @@ +#if __has_include() +#include +#define HAVE_SYS_HWCAP_H +#endif + +#ifndef _IFUNC_ARG_HWCAP +#define _IFUNC_ARG_HWCAP (1ULL << 62) +#endif +#ifndef AT_HWCAP +#define AT_HWCAP 16 +#endif +#ifndef HWCAP_CPUID +#define HWCAP_CPUID (1 << 11) +#endif +#ifndef HWCAP_FP +#define HWCAP_FP (1 << 0) +#endif +#ifndef HWCAP_ASIMD +#define HWCAP_ASIMD (1 << 1) +#endif +#ifndef HWCAP_AES +#define HWCAP_AES (1 << 3) +#endif +#ifndef HWCAP_PMULL +#define HWCAP_PMULL (1 << 4) +#endif +#ifndef HWCAP_SHA1 +#define HWCAP_SHA1 (1 << 5) +#endif +#ifndef HWCAP_SHA2 +#define HWCAP_SHA2 (1 << 6) +#endif +#ifndef HWCAP_CRC32 +#define HWCAP_CRC32 (1 << 7) +#endif +#ifndef HWCAP_ATOMICS +#define HWCAP_ATOMICS (1 << 8) +#endif +#ifndef HWCAP_FPHP +#define HWCAP_FPHP (1 << 9) +#endif +#ifndef HWCAP_ASIMDHP +#define HWCAP_ASIMDHP (1 << 10) +#endif +#ifndef HWCAP_ASIMDRDM +#define HWCAP_ASIMDRDM (1 << 12) +#endif +#ifndef HWCAP_JSCVT +#define HWCAP_JSCVT (1 << 13) +#endif +#ifndef HWCAP_FCMA +#define HWCAP_FCMA (1 << 14) +#endif +#ifndef HWCAP_LRCPC +#define HWCAP_LRCPC (1 << 15) +#endif +#ifndef HWCAP_DCPOP +#define HWCAP_DCPOP (1 << 16) +#endif +#ifndef HWCAP_SHA3 +#define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SM3 +#define HWCAP_SM3 (1 << 18) +#endif +#ifndef HWCAP_SM4 +#define HWCAP_SM4 (1 << 19) +#endif +#ifndef HWCAP_ASIMDDP +#define HWCAP_ASIMDDP (1 << 20) +#endif +#ifndef HWCAP_SHA512 +#define HWCAP_SHA512 (1 << 21) +#endif +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif +#ifndef HWCAP_ASIMDFHM +#define HWCAP_ASIMDFHM (1 << 23) +#endif +#ifndef HWCAP_DIT +#define HWCAP_DIT (1 << 24) +#endif +#ifndef HWCAP_ILRCPC +#define HWCAP_ILRCPC (1 << 26) +#endif +#ifndef HWCAP_FLAGM +#define HWCAP_FLAGM (1 << 27) +#endif +#ifndef HWCAP_SSBS +#define HWCAP_SSBS (1 << 28) +#endif +#ifndef HWCAP_SB +#define HWCAP_SB (1 << 29) +#endif + +#ifndef AT_HWCAP2 +#define AT_HWCAP2 26 +#endif +#ifndef HWCAP2_DCPODP +#define HWCAP2_DCPODP (1 << 0) +#endif +#ifndef HWCAP2_SVE2 +#define HWCAP2_SVE2 (1 << 1) +#endif +#ifndef HWCAP2_SVEAES +#define HWCAP2_SVEAES (1 << 2) +#endif +#ifndef HWCAP2_SVEPMULL +#define HWCAP2_SVEPMULL (1 << 3) +#endif +#ifndef HWCAP2_SVEBITPERM +#define HWCAP2_SVEBITPERM (1 << 4) +#endif +#ifndef HWCAP2_SVESHA3 +#define HWCAP2_SVESHA3 (1 << 5) +#endif +#ifndef HWCAP2_SVESM4 +#define HWCAP2_SVESM4 (1 << 6) +#endif +#ifndef HWCAP2_FLAGM2 +#define HWCAP2_FLAGM2 (1 << 7) +#endif +#ifndef HWCAP2_FRINT +#define HWCAP2_FRINT (1 << 8) +#endif +#ifndef HWCAP2_SVEI8MM +#define HWCAP2_SVEI8MM (1 << 9) +#endif +#ifndef HWCAP2_SVEF32MM +#define HWCAP2_SVEF32MM (1 << 10) +#endif +#ifndef HWCAP2_SVEF64MM +#define HWCAP2_SVEF64MM (1 << 11) +#endif +#ifndef HWCAP2_SVEBF16 +#define HWCAP2_SVEBF16 (1 << 12) +#endif +#ifndef HWCAP2_I8MM +#define HWCAP2_I8MM (1 << 13) +#endif +#ifndef HWCAP2_BF16 +#define HWCAP2_BF16 (1 << 14) +#endif +#ifndef HWCAP2_DGH +#define HWCAP2_DGH (1 << 15) +#endif +#ifndef HWCAP2_RNG +#define HWCAP2_RNG (1 << 16) +#endif +#ifndef HWCAP2_BTI +#define HWCAP2_BTI (1 << 17) +#endif +#ifndef HWCAP2_MTE +#define HWCAP2_MTE (1 << 18) +#endif +#ifndef HWCAP2_RPRES +#define HWCAP2_RPRES (1 << 21) +#endif +#ifndef HWCAP2_MTE3 +#define HWCAP2_MTE3 (1 << 22) +#endif +#ifndef HWCAP2_SME +#define HWCAP2_SME (1 << 23) +#endif +#ifndef HWCAP2_SME_I16I64 +#define HWCAP2_SME_I16I64 (1 << 24) +#endif +#ifndef HWCAP2_SME_F64F64 +#define HWCAP2_SME_F64F64 (1 << 25) +#endif +#ifndef HWCAP2_WFXT +#define HWCAP2_WFXT (1UL << 31) +#endif +#ifndef HWCAP2_EBF16 +#define HWCAP2_EBF16 (1ULL << 32) +#endif +#ifndef HWCAP2_SVE_EBF16 +#define HWCAP2_SVE_EBF16 (1ULL << 33) +#endif diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc new file mode 100644 index 0000000000000000000000000000000000000000..94bf64a5b0b0fad54f791df5605b303be9eb637e --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc @@ -0,0 +1,28 @@ +#include +#include +#include + +static bool __isExynos9810(void) { + char arch[PROP_VALUE_MAX]; + return __system_property_get("ro.arch", arch) > 0 && + strncmp(arch, "exynos9810", sizeof("exynos9810") - 1) == 0; +} + +static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { + unsigned long hwcap = getauxval(AT_HWCAP); + _Bool result = (hwcap & HWCAP_ATOMICS) != 0; + if (result) { + // Some cores in the Exynos 9810 CPU are ARMv8.2 and others are ARMv8.0; + // only the former support LSE atomics. However, the kernel in the + // initial Android 8.0 release of Galaxy S9/S9+ devices incorrectly + // reported the feature as being supported. + // + // The kernel appears to have been corrected to mark it unsupported as of + // the Android 9.0 release on those devices, and this issue has not been + // observed anywhere else. Thus, this workaround may be removed if + // compiler-rt ever drops support for Android 8.0. + if (__isExynos9810()) + result = false; + } + __aarch64_have_lse_atomics = result; +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/freebsd.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/freebsd.inc new file mode 100644 index 0000000000000000000000000000000000000000..4a1f9c2c27c8286bd99762d02523f80850887d80 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/freebsd.inc @@ -0,0 +1,5 @@ +static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { + unsigned long hwcap; + int result = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); + __aarch64_have_lse_atomics = result == 0 && (hwcap & HWCAP_ATOMICS) != 0; +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/fuchsia.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/fuchsia.inc new file mode 100644 index 0000000000000000000000000000000000000000..91eac70ae6c5e9a1fdce7832763f8175f7c93ff1 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/fuchsia.inc @@ -0,0 +1,12 @@ +#include +#include + +static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { + // This ensures the vDSO is a direct link-time dependency of anything that + // needs this initializer code. +#pragma comment(lib, "zircon") + uint32_t features; + zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features); + __aarch64_have_lse_atomics = + status == ZX_OK && (features & ZX_ARM64_FEATURE_ISA_ATOMICS) != 0; +} diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/sysauxv.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/sysauxv.inc new file mode 100644 index 0000000000000000000000000000000000000000..6642c1f5b60b39811b5c201868b653500dee226f --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/sysauxv.inc @@ -0,0 +1,6 @@ +#include + +static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { + unsigned long hwcap = getauxval(AT_HWCAP); + __aarch64_have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0; +} diff --git a/compiler-rt/lib/builtins/cpu_model/cpu_model.h b/compiler-rt/lib/builtins/cpu_model/cpu_model.h new file mode 100644 index 0000000000000000000000000000000000000000..924ca89cf60f5c4483aee468a1719189a4dcc3e8 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/cpu_model.h @@ -0,0 +1,41 @@ +//===-- cpu_model_common.c - Utilities for cpu model detection ----*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements common utilities for runtime cpu model detection. +// +//===----------------------------------------------------------------------===// + +#ifndef COMPILER_RT_LIB_BUILTINS_CPU_MODEL_COMMON_H +#define COMPILER_RT_LIB_BUILTINS_CPU_MODEL_COMMON_H + +#define bool int +#define true 1 +#define false 0 + +#ifndef __has_attribute +#define __has_attribute(attr) 0 +#endif + +#if __has_attribute(constructor) +#if __GNUC__ >= 9 +// Ordinarily init priorities below 101 are disallowed as they are reserved for +// the implementation. However, we are the implementation, so silence the +// diagnostic, since it doesn't apply to us. +#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" +#endif +// We're choosing init priority 90 to force our constructors to run before any +// constructors in the end user application (starting at priority 101). This +// value matches the libgcc choice for the same functions. +#define CONSTRUCTOR_ATTRIBUTE __attribute__((constructor(90))) +#else +// FIXME: For MSVC, we should make a function pointer global in .CRT$X?? so that +// this runs during initialization. +#define CONSTRUCTOR_ATTRIBUTE +#endif + +#endif diff --git a/compiler-rt/lib/builtins/cpu_model.c b/compiler-rt/lib/builtins/cpu_model/x86.c similarity index 57% rename from compiler-rt/lib/builtins/cpu_model.c rename to compiler-rt/lib/builtins/cpu_model/x86.c index b0ec5e51e96d491207d6b82712029eac4a4db3d1..9d9a5d3f1542cdee37320fa286d117b67deb1b22 100644 --- a/compiler-rt/lib/builtins/cpu_model.c +++ b/compiler-rt/lib/builtins/cpu_model/x86.c @@ -1,4 +1,4 @@ -//===-- cpu_model.c - Support for __cpu_model builtin ------------*- C -*-===// +//===-- cpu_model/x86.c - Support for __cpu_model builtin --------*- C -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,42 +8,21 @@ // // This file is based on LLVM's lib/Support/Host.cpp. // It implements the operating system Host concept and builtin -// __cpu_model for the compiler_rt library for x86 and -// __aarch64_have_lse_atomics, __aarch64_cpu_features for AArch64. +// __cpu_model for the compiler_rt library for x86. // //===----------------------------------------------------------------------===// -#ifndef __has_attribute -#define __has_attribute(attr) 0 -#endif +#include "cpu_model.h" -#if __has_attribute(constructor) -#if __GNUC__ >= 9 -// Ordinarily init priorities below 101 are disallowed as they are reserved for the -// implementation. However, we are the implementation, so silence the diagnostic, -// since it doesn't apply to us. -#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" -#endif -// We're choosing init priority 90 to force our constructors to run before any -// constructors in the end user application (starting at priority 101). This value -// matches the libgcc choice for the same functions. -#define CONSTRUCTOR_ATTRIBUTE __attribute__((constructor(90))) -#else -// FIXME: For MSVC, we should make a function pointer global in .CRT$X?? so that -// this runs during initialization. -#define CONSTRUCTOR_ATTRIBUTE +#if !(defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ + defined(_M_X64)) +#error This file is intended only for x86-based targets #endif -#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ - defined(_M_X64)) && \ - (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) +#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) #include -#define bool int -#define true 1 -#define false 0 - #ifdef _MSC_VER #include #endif @@ -319,12 +298,12 @@ static void detectX86FamilyModel(unsigned EAX, unsigned *Family, } } -static const char * -getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, - const unsigned *Features, - unsigned *Type, unsigned *Subtype) { -#define testFeature(F) \ - (Features[F / 32] & (1 << (F % 32))) != 0 +static const char *getIntelProcessorTypeAndSubtype(unsigned Family, + unsigned Model, + const unsigned *Features, + unsigned *Type, + unsigned *Subtype) { +#define testFeature(F) (Features[F / 32] & (1 << (F % 32))) != 0 // We select CPU strings to match the code in Host.cpp, but we don't use them // in compiler-rt. @@ -357,7 +336,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. // As found in a Summer 2010 model iMac. case 0x1f: - case 0x2e: // Nehalem EX + case 0x2e: // Nehalem EX CPU = "nehalem"; *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_NEHALEM; @@ -378,7 +357,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, *Subtype = INTEL_COREI7_SANDYBRIDGE; break; case 0x3a: - case 0x3e: // Ivy Bridge EP + case 0x3e: // Ivy Bridge EP CPU = "ivybridge"; *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_IVYBRIDGE; @@ -405,12 +384,12 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, break; // Skylake: - case 0x4e: // Skylake mobile - case 0x5e: // Skylake desktop - case 0x8e: // Kaby Lake mobile - case 0x9e: // Kaby Lake desktop - case 0xa5: // Comet Lake-H/S - case 0xa6: // Comet Lake-U + case 0x4e: // Skylake mobile + case 0x5e: // Skylake desktop + case 0x8e: // Kaby Lake mobile + case 0x9e: // Kaby Lake desktop + case 0xa5: // Comet Lake-H/S + case 0xa6: // Comet Lake-U CPU = "skylake"; *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_SKYLAKE; @@ -609,10 +588,11 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, return CPU; } -static const char * -getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, - const unsigned *Features, - unsigned *Type, unsigned *Subtype) { +static const char *getAMDProcessorTypeAndSubtype(unsigned Family, + unsigned Model, + const unsigned *Features, + unsigned *Type, + unsigned *Subtype) { // We select CPU strings to match the code in Host.cpp, but we don't use them // in compiler-rt. const char *CPU = 0; @@ -667,37 +647,59 @@ getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 23: CPU = "znver1"; *Type = AMDFAM17H; - if ((Model >= 0x30 && Model <= 0x3f) || Model == 0x71) { + if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) || + (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) || + (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) || + (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) || + (Model >= 0xa0 && Model <= 0xaf)) { + // Family 17h Models 30h-3Fh (Starship) Zen 2 + // Family 17h Models 47h (Cardinal) Zen 2 + // Family 17h Models 60h-67h (Renoir) Zen 2 + // Family 17h Models 68h-6Fh (Lucienne) Zen 2 + // Family 17h Models 70h-7Fh (Matisse) Zen 2 + // Family 17h Models 84h-87h (ProjectX) Zen 2 + // Family 17h Models 90h-97h (VanGogh) Zen 2 + // Family 17h Models 98h-9Fh (Mero) Zen 2 + // Family 17h Models A0h-AFh (Mendocino) Zen 2 CPU = "znver2"; *Subtype = AMDFAM17H_ZNVER2; - break; // 30h-3fh, 71h: Zen2 + break; } - if (Model <= 0x0f) { + if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) { + // Family 17h Models 10h-1Fh (Raven1) Zen + // Family 17h Models 10h-1Fh (Picasso) Zen+ + // Family 17h Models 20h-2Fh (Raven2 x86) Zen *Subtype = AMDFAM17H_ZNVER1; - break; // 00h-0Fh: Zen1 + break; } break; case 25: CPU = "znver3"; *Type = AMDFAM19H; - if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x5f)) { - // Family 19h Models 00h-0Fh - Zen3 - // Family 19h Models 20h-2Fh - Zen3 - // Family 19h Models 30h-3Fh - Zen3 - // Family 19h Models 40h-4Fh - Zen3+ - // Family 19h Models 50h-5Fh - Zen3+ + if ((Model <= 0x0f) || (Model >= 0x20 && Model <= 0x2f) || + (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) || + (Model >= 0x50 && Model <= 0x5f)) { + // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3 + // Family 19h Models 20h-2Fh (Vermeer) Zen 3 + // Family 19h Models 30h-3Fh (Badami) Zen 3 + // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+ + // Family 19h Models 50h-5Fh (Cezanne) Zen 3 *Subtype = AMDFAM19H_ZNVER3; break; } - if ((Model >= 0x10 && Model <= 0x1f) || - (Model >= 0x60 && Model <= 0x74) || - (Model >= 0x78 && Model <= 0x7b) || - (Model >= 0xA0 && Model <= 0xAf)) { + if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) || + (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) || + (Model >= 0xa0 && Model <= 0xaf)) { + // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4 + // Family 19h Models 60h-6Fh (Raphael) Zen 4 + // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4 + // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4 + // Family 19h Models A0h-AFh (Stones-Dense) Zen 4 CPU = "znver4"; *Subtype = AMDFAM19H_ZNVER4; break; // "znver4" } - break; + break; // family 19h default: break; // Unknown AMD CPU. } @@ -710,8 +712,7 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, unsigned EAX = 0, EBX = 0; #define hasFeature(F) ((Features[F / 32] >> (F % 32)) & 1) -#define setFeature(F) \ - Features[F / 32] |= 1U << (F % 32) +#define setFeature(F) Features[F / 32] |= 1U << (F % 32) if ((EDX >> 15) & 1) setFeature(FEATURE_CMOV); @@ -938,567 +939,4 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) { return 0; } -#elif defined(__aarch64__) - -// LSE support detection for out-of-line atomics -// using HWCAP and Auxiliary vector -_Bool __aarch64_have_lse_atomics - __attribute__((visibility("hidden"), nocommon)); - -#if defined(__has_include) -#if __has_include() -#include - -#if __has_include() -#include -#else -typedef struct __ifunc_arg_t { - unsigned long _size; - unsigned long _hwcap; - unsigned long _hwcap2; -} __ifunc_arg_t; -#endif // __has_include() - -#if __has_include() -#include - -#if defined(__ANDROID__) -#include -#include -#elif defined(__Fuchsia__) -#include -#include -#endif - -#ifndef _IFUNC_ARG_HWCAP -#define _IFUNC_ARG_HWCAP (1ULL << 62) -#endif -#ifndef AT_HWCAP -#define AT_HWCAP 16 -#endif -#ifndef HWCAP_CPUID -#define HWCAP_CPUID (1 << 11) -#endif -#ifndef HWCAP_FP -#define HWCAP_FP (1 << 0) -#endif -#ifndef HWCAP_ASIMD -#define HWCAP_ASIMD (1 << 1) -#endif -#ifndef HWCAP_AES -#define HWCAP_AES (1 << 3) -#endif -#ifndef HWCAP_PMULL -#define HWCAP_PMULL (1 << 4) -#endif -#ifndef HWCAP_SHA1 -#define HWCAP_SHA1 (1 << 5) -#endif -#ifndef HWCAP_SHA2 -#define HWCAP_SHA2 (1 << 6) -#endif -#ifndef HWCAP_ATOMICS -#define HWCAP_ATOMICS (1 << 8) -#endif -#ifndef HWCAP_FPHP -#define HWCAP_FPHP (1 << 9) -#endif -#ifndef HWCAP_ASIMDHP -#define HWCAP_ASIMDHP (1 << 10) -#endif -#ifndef HWCAP_ASIMDRDM -#define HWCAP_ASIMDRDM (1 << 12) -#endif -#ifndef HWCAP_JSCVT -#define HWCAP_JSCVT (1 << 13) -#endif -#ifndef HWCAP_FCMA -#define HWCAP_FCMA (1 << 14) -#endif -#ifndef HWCAP_LRCPC -#define HWCAP_LRCPC (1 << 15) -#endif -#ifndef HWCAP_DCPOP -#define HWCAP_DCPOP (1 << 16) -#endif -#ifndef HWCAP_SHA3 -#define HWCAP_SHA3 (1 << 17) -#endif -#ifndef HWCAP_SM3 -#define HWCAP_SM3 (1 << 18) -#endif -#ifndef HWCAP_SM4 -#define HWCAP_SM4 (1 << 19) -#endif -#ifndef HWCAP_ASIMDDP -#define HWCAP_ASIMDDP (1 << 20) -#endif -#ifndef HWCAP_SHA512 -#define HWCAP_SHA512 (1 << 21) -#endif -#ifndef HWCAP_SVE -#define HWCAP_SVE (1 << 22) -#endif -#ifndef HWCAP_ASIMDFHM -#define HWCAP_ASIMDFHM (1 << 23) -#endif -#ifndef HWCAP_DIT -#define HWCAP_DIT (1 << 24) -#endif -#ifndef HWCAP_ILRCPC -#define HWCAP_ILRCPC (1 << 26) -#endif -#ifndef HWCAP_FLAGM -#define HWCAP_FLAGM (1 << 27) -#endif -#ifndef HWCAP_SSBS -#define HWCAP_SSBS (1 << 28) -#endif -#ifndef HWCAP_SB -#define HWCAP_SB (1 << 29) -#endif - -#ifndef AT_HWCAP2 -#define AT_HWCAP2 26 -#endif -#ifndef HWCAP2_DCPODP -#define HWCAP2_DCPODP (1 << 0) -#endif -#ifndef HWCAP2_SVE2 -#define HWCAP2_SVE2 (1 << 1) -#endif -#ifndef HWCAP2_SVEAES -#define HWCAP2_SVEAES (1 << 2) -#endif -#ifndef HWCAP2_SVEPMULL -#define HWCAP2_SVEPMULL (1 << 3) -#endif -#ifndef HWCAP2_SVEBITPERM -#define HWCAP2_SVEBITPERM (1 << 4) -#endif -#ifndef HWCAP2_SVESHA3 -#define HWCAP2_SVESHA3 (1 << 5) -#endif -#ifndef HWCAP2_SVESM4 -#define HWCAP2_SVESM4 (1 << 6) -#endif -#ifndef HWCAP2_FLAGM2 -#define HWCAP2_FLAGM2 (1 << 7) -#endif -#ifndef HWCAP2_FRINT -#define HWCAP2_FRINT (1 << 8) -#endif -#ifndef HWCAP2_SVEI8MM -#define HWCAP2_SVEI8MM (1 << 9) -#endif -#ifndef HWCAP2_SVEF32MM -#define HWCAP2_SVEF32MM (1 << 10) -#endif -#ifndef HWCAP2_SVEF64MM -#define HWCAP2_SVEF64MM (1 << 11) -#endif -#ifndef HWCAP2_SVEBF16 -#define HWCAP2_SVEBF16 (1 << 12) -#endif -#ifndef HWCAP2_I8MM -#define HWCAP2_I8MM (1 << 13) -#endif -#ifndef HWCAP2_BF16 -#define HWCAP2_BF16 (1 << 14) -#endif -#ifndef HWCAP2_DGH -#define HWCAP2_DGH (1 << 15) -#endif -#ifndef HWCAP2_RNG -#define HWCAP2_RNG (1 << 16) -#endif -#ifndef HWCAP2_BTI -#define HWCAP2_BTI (1 << 17) -#endif -#ifndef HWCAP2_MTE -#define HWCAP2_MTE (1 << 18) -#endif -#ifndef HWCAP2_RPRES -#define HWCAP2_RPRES (1 << 21) -#endif -#ifndef HWCAP2_MTE3 -#define HWCAP2_MTE3 (1 << 22) -#endif -#ifndef HWCAP2_SME -#define HWCAP2_SME (1 << 23) -#endif -#ifndef HWCAP2_SME_I16I64 -#define HWCAP2_SME_I16I64 (1 << 24) -#endif -#ifndef HWCAP2_SME_F64F64 -#define HWCAP2_SME_F64F64 (1 << 25) -#endif -#ifndef HWCAP2_WFXT -#define HWCAP2_WFXT (1UL << 31) -#endif -#ifndef HWCAP2_EBF16 -#define HWCAP2_EBF16 (1ULL << 32) -#endif -#ifndef HWCAP2_SVE_EBF16 -#define HWCAP2_SVE_EBF16 (1ULL << 33) -#endif - -// Detect Exynos 9810 CPU -#define IF_EXYNOS9810 \ - char arch[PROP_VALUE_MAX]; \ - if (__system_property_get("ro.arch", arch) > 0 && \ - strncmp(arch, "exynos9810", sizeof("exynos9810") - 1) == 0) - -static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { -#if defined(__FreeBSD__) - unsigned long hwcap; - int result = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); - __aarch64_have_lse_atomics = result == 0 && (hwcap & HWCAP_ATOMICS) != 0; -#elif defined(__Fuchsia__) - // This ensures the vDSO is a direct link-time dependency of anything that - // needs this initializer code. -#pragma comment(lib, "zircon") - uint32_t features; - zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features); - __aarch64_have_lse_atomics = - status == ZX_OK && (features & ZX_ARM64_FEATURE_ISA_ATOMICS) != 0; -#else - unsigned long hwcap = getauxval(AT_HWCAP); - _Bool result = (hwcap & HWCAP_ATOMICS) != 0; -#if defined(__ANDROID__) - if (result) { - // Some cores in the Exynos 9810 CPU are ARMv8.2 and others are ARMv8.0; - // only the former support LSE atomics. However, the kernel in the - // initial Android 8.0 release of Galaxy S9/S9+ devices incorrectly - // reported the feature as being supported. - // - // The kernel appears to have been corrected to mark it unsupported as of - // the Android 9.0 release on those devices, and this issue has not been - // observed anywhere else. Thus, this workaround may be removed if - // compiler-rt ever drops support for Android 8.0. - IF_EXYNOS9810 result = false; - } -#endif // defined(__ANDROID__) - __aarch64_have_lse_atomics = result; -#endif // defined(__FreeBSD__) -} - -#if !defined(DISABLE_AARCH64_FMV) -// CPUFeatures must correspond to the same AArch64 features in -// AArch64TargetParser.h -enum CPUFeatures { - FEAT_RNG, - FEAT_FLAGM, - FEAT_FLAGM2, - FEAT_FP16FML, - FEAT_DOTPROD, - FEAT_SM4, - FEAT_RDM, - FEAT_LSE, - FEAT_FP, - FEAT_SIMD, - FEAT_CRC, - FEAT_SHA1, - FEAT_SHA2, - FEAT_SHA3, - FEAT_AES, - FEAT_PMULL, - FEAT_FP16, - FEAT_DIT, - FEAT_DPB, - FEAT_DPB2, - FEAT_JSCVT, - FEAT_FCMA, - FEAT_RCPC, - FEAT_RCPC2, - FEAT_FRINTTS, - FEAT_DGH, - FEAT_I8MM, - FEAT_BF16, - FEAT_EBF16, - FEAT_RPRES, - FEAT_SVE, - FEAT_SVE_BF16, - FEAT_SVE_EBF16, - FEAT_SVE_I8MM, - FEAT_SVE_F32MM, - FEAT_SVE_F64MM, - FEAT_SVE2, - FEAT_SVE_AES, - FEAT_SVE_PMULL128, - FEAT_SVE_BITPERM, - FEAT_SVE_SHA3, - FEAT_SVE_SM4, - FEAT_SME, - FEAT_MEMTAG, - FEAT_MEMTAG2, - FEAT_MEMTAG3, - FEAT_SB, - FEAT_PREDRES, - FEAT_SSBS, - FEAT_SSBS2, - FEAT_BTI, - FEAT_LS64, - FEAT_LS64_V, - FEAT_LS64_ACCDATA, - FEAT_WFXT, - FEAT_SME_F64, - FEAT_SME_I64, - FEAT_SME2, - FEAT_RCPC3, - FEAT_MAX, - FEAT_EXT = 62, // Reserved to indicate presence of additional features field - // in __aarch64_cpu_features - FEAT_INIT // Used as flag of features initialization completion -}; - -// Architecture features used -// in Function Multi Versioning -struct { - unsigned long long features; - // As features grows new fields could be added -} __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon)); - -static void __init_cpu_features_constructor(unsigned long hwcap, - const __ifunc_arg_t *arg) { -#define setCPUFeature(F) __aarch64_cpu_features.features |= 1ULL << F -#define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr)) -#define extractBits(val, start, number) \ - (val & ((1ULL << number) - 1ULL) << start) >> start - unsigned long hwcap2 = 0; - if (hwcap & _IFUNC_ARG_HWCAP) - hwcap2 = arg->_hwcap2; - if (hwcap & HWCAP_CRC32) - setCPUFeature(FEAT_CRC); - if (hwcap & HWCAP_PMULL) - setCPUFeature(FEAT_PMULL); - if (hwcap & HWCAP_FLAGM) - setCPUFeature(FEAT_FLAGM); - if (hwcap2 & HWCAP2_FLAGM2) { - setCPUFeature(FEAT_FLAGM); - setCPUFeature(FEAT_FLAGM2); - } - if (hwcap & HWCAP_SM3 && hwcap & HWCAP_SM4) - setCPUFeature(FEAT_SM4); - if (hwcap & HWCAP_ASIMDDP) - setCPUFeature(FEAT_DOTPROD); - if (hwcap & HWCAP_ASIMDFHM) - setCPUFeature(FEAT_FP16FML); - if (hwcap & HWCAP_FPHP) { - setCPUFeature(FEAT_FP16); - setCPUFeature(FEAT_FP); - } - if (hwcap & HWCAP_DIT) - setCPUFeature(FEAT_DIT); - if (hwcap & HWCAP_ASIMDRDM) - setCPUFeature(FEAT_RDM); - if (hwcap & HWCAP_ILRCPC) - setCPUFeature(FEAT_RCPC2); - if (hwcap & HWCAP_AES) - setCPUFeature(FEAT_AES); - if (hwcap & HWCAP_SHA1) - setCPUFeature(FEAT_SHA1); - if (hwcap & HWCAP_SHA2) - setCPUFeature(FEAT_SHA2); - if (hwcap & HWCAP_JSCVT) - setCPUFeature(FEAT_JSCVT); - if (hwcap & HWCAP_FCMA) - setCPUFeature(FEAT_FCMA); - if (hwcap & HWCAP_SB) - setCPUFeature(FEAT_SB); - if (hwcap & HWCAP_SSBS) - setCPUFeature(FEAT_SSBS2); - if (hwcap2 & HWCAP2_MTE) { - setCPUFeature(FEAT_MEMTAG); - setCPUFeature(FEAT_MEMTAG2); - } - if (hwcap2 & HWCAP2_MTE3) { - setCPUFeature(FEAT_MEMTAG); - setCPUFeature(FEAT_MEMTAG2); - setCPUFeature(FEAT_MEMTAG3); - } - if (hwcap2 & HWCAP2_SVEAES) - setCPUFeature(FEAT_SVE_AES); - if (hwcap2 & HWCAP2_SVEPMULL) { - setCPUFeature(FEAT_SVE_AES); - setCPUFeature(FEAT_SVE_PMULL128); - } - if (hwcap2 & HWCAP2_SVEBITPERM) - setCPUFeature(FEAT_SVE_BITPERM); - if (hwcap2 & HWCAP2_SVESHA3) - setCPUFeature(FEAT_SVE_SHA3); - if (hwcap2 & HWCAP2_SVESM4) - setCPUFeature(FEAT_SVE_SM4); - if (hwcap2 & HWCAP2_DCPODP) - setCPUFeature(FEAT_DPB2); - if (hwcap & HWCAP_ATOMICS) - setCPUFeature(FEAT_LSE); - if (hwcap2 & HWCAP2_RNG) - setCPUFeature(FEAT_RNG); - if (hwcap2 & HWCAP2_I8MM) - setCPUFeature(FEAT_I8MM); - if (hwcap2 & HWCAP2_EBF16) - setCPUFeature(FEAT_EBF16); - if (hwcap2 & HWCAP2_SVE_EBF16) - setCPUFeature(FEAT_SVE_EBF16); - if (hwcap2 & HWCAP2_DGH) - setCPUFeature(FEAT_DGH); - if (hwcap2 & HWCAP2_FRINT) - setCPUFeature(FEAT_FRINTTS); - if (hwcap2 & HWCAP2_SVEI8MM) - setCPUFeature(FEAT_SVE_I8MM); - if (hwcap2 & HWCAP2_SVEF32MM) - setCPUFeature(FEAT_SVE_F32MM); - if (hwcap2 & HWCAP2_SVEF64MM) - setCPUFeature(FEAT_SVE_F64MM); - if (hwcap2 & HWCAP2_BTI) - setCPUFeature(FEAT_BTI); - if (hwcap2 & HWCAP2_RPRES) - setCPUFeature(FEAT_RPRES); - if (hwcap2 & HWCAP2_WFXT) - setCPUFeature(FEAT_WFXT); - if (hwcap2 & HWCAP2_SME) - setCPUFeature(FEAT_SME); - if (hwcap2 & HWCAP2_SME_I16I64) - setCPUFeature(FEAT_SME_I64); - if (hwcap2 & HWCAP2_SME_F64F64) - setCPUFeature(FEAT_SME_F64); - if (hwcap & HWCAP_CPUID) { - unsigned long ftr; - getCPUFeature(ID_AA64PFR1_EL1, ftr); - // ID_AA64PFR1_EL1.MTE >= 0b0001 - if (extractBits(ftr, 8, 4) >= 0x1) - setCPUFeature(FEAT_MEMTAG); - // ID_AA64PFR1_EL1.SSBS == 0b0001 - if (extractBits(ftr, 4, 4) == 0x1) - setCPUFeature(FEAT_SSBS); - // ID_AA64PFR1_EL1.SME == 0b0010 - if (extractBits(ftr, 24, 4) == 0x2) - setCPUFeature(FEAT_SME2); - getCPUFeature(ID_AA64PFR0_EL1, ftr); - // ID_AA64PFR0_EL1.FP != 0b1111 - if (extractBits(ftr, 16, 4) != 0xF) { - setCPUFeature(FEAT_FP); - // ID_AA64PFR0_EL1.AdvSIMD has the same value as ID_AA64PFR0_EL1.FP - setCPUFeature(FEAT_SIMD); - } - // ID_AA64PFR0_EL1.SVE != 0b0000 - if (extractBits(ftr, 32, 4) != 0x0) { - // get ID_AA64ZFR0_EL1, that name supported - // if sve enabled only - getCPUFeature(S3_0_C0_C4_4, ftr); - // ID_AA64ZFR0_EL1.SVEver == 0b0000 - if (extractBits(ftr, 0, 4) == 0x0) - setCPUFeature(FEAT_SVE); - // ID_AA64ZFR0_EL1.SVEver == 0b0001 - if (extractBits(ftr, 0, 4) == 0x1) - setCPUFeature(FEAT_SVE2); - // ID_AA64ZFR0_EL1.BF16 != 0b0000 - if (extractBits(ftr, 20, 4) != 0x0) - setCPUFeature(FEAT_SVE_BF16); - } - getCPUFeature(ID_AA64ISAR0_EL1, ftr); - // ID_AA64ISAR0_EL1.SHA3 != 0b0000 - if (extractBits(ftr, 32, 4) != 0x0) - setCPUFeature(FEAT_SHA3); - getCPUFeature(ID_AA64ISAR1_EL1, ftr); - // ID_AA64ISAR1_EL1.DPB >= 0b0001 - if (extractBits(ftr, 0, 4) >= 0x1) - setCPUFeature(FEAT_DPB); - // ID_AA64ISAR1_EL1.LRCPC != 0b0000 - if (extractBits(ftr, 20, 4) != 0x0) - setCPUFeature(FEAT_RCPC); - // ID_AA64ISAR1_EL1.LRCPC == 0b0011 - if (extractBits(ftr, 20, 4) == 0x3) - setCPUFeature(FEAT_RCPC3); - // ID_AA64ISAR1_EL1.SPECRES == 0b0001 - if (extractBits(ftr, 40, 4) == 0x2) - setCPUFeature(FEAT_PREDRES); - // ID_AA64ISAR1_EL1.BF16 != 0b0000 - if (extractBits(ftr, 44, 4) != 0x0) - setCPUFeature(FEAT_BF16); - // ID_AA64ISAR1_EL1.LS64 >= 0b0001 - if (extractBits(ftr, 60, 4) >= 0x1) - setCPUFeature(FEAT_LS64); - // ID_AA64ISAR1_EL1.LS64 >= 0b0010 - if (extractBits(ftr, 60, 4) >= 0x2) - setCPUFeature(FEAT_LS64_V); - // ID_AA64ISAR1_EL1.LS64 >= 0b0011 - if (extractBits(ftr, 60, 4) >= 0x3) - setCPUFeature(FEAT_LS64_ACCDATA); - } else { - // Set some features in case of no CPUID support - if (hwcap & (HWCAP_FP | HWCAP_FPHP)) { - setCPUFeature(FEAT_FP); - // FP and AdvSIMD fields have the same value - setCPUFeature(FEAT_SIMD); - } - if (hwcap & HWCAP_DCPOP || hwcap2 & HWCAP2_DCPODP) - setCPUFeature(FEAT_DPB); - if (hwcap & HWCAP_LRCPC || hwcap & HWCAP_ILRCPC) - setCPUFeature(FEAT_RCPC); - if (hwcap2 & HWCAP2_BF16 || hwcap2 & HWCAP2_EBF16) - setCPUFeature(FEAT_BF16); - if (hwcap2 & HWCAP2_SVEBF16) - setCPUFeature(FEAT_SVE_BF16); - if (hwcap2 & HWCAP2_SVE2 && hwcap & HWCAP_SVE) - setCPUFeature(FEAT_SVE2); - if (hwcap & HWCAP_SHA3) - setCPUFeature(FEAT_SHA3); - } - setCPUFeature(FEAT_INIT); -} - -void __init_cpu_features_resolver(unsigned long hwcap, - const __ifunc_arg_t *arg) { - if (__aarch64_cpu_features.features) - return; -#if defined(__ANDROID__) - // ifunc resolvers don't have hwcaps in arguments on Android API lower - // than 30. If so, set feature detection done and keep all CPU features - // unsupported (zeros). To detect this case in runtime we check existence - // of memfd_create function from Standard C library which was introduced in - // Android API 30. - int memfd_create(const char *, unsigned int) __attribute__((weak)); - if (!memfd_create) - return; -#endif // defined(__ANDROID__) - __init_cpu_features_constructor(hwcap, arg); -} - -void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) { - unsigned long hwcap; - unsigned long hwcap2; - // CPU features already initialized. - if (__aarch64_cpu_features.features) - return; -#if defined(__FreeBSD__) - int res = 0; - res = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); - res |= elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2); - if (res) - return; -#else -#if defined(__ANDROID__) - // Don't set any CPU features, - // detection could be wrong on Exynos 9810. - IF_EXYNOS9810 return; -#endif // defined(__ANDROID__) - hwcap = getauxval(AT_HWCAP); - hwcap2 = getauxval(AT_HWCAP2); -#endif // defined(__FreeBSD__) - __ifunc_arg_t arg; - arg._size = sizeof(__ifunc_arg_t); - arg._hwcap = hwcap; - arg._hwcap2 = hwcap2; - __init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg); -#undef extractBits -#undef getCPUFeature -#undef setCPUFeature -#undef IF_EXYNOS9810 -} -#endif // !defined(DISABLE_AARCH64_FMV) -#endif // defined(__has_include) -#endif // __has_include() -#endif // __has_include() -#endif // defined(__aarch64__) +#endif // defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) diff --git a/compiler-rt/lib/builtins/fp_lib.h b/compiler-rt/lib/builtins/fp_lib.h index 43bbdd5f8736575b90a1a9c55681d3bbe01c7416..af406e760497a42590e7de5fb94da1a0b49684de 100644 --- a/compiler-rt/lib/builtins/fp_lib.h +++ b/compiler-rt/lib/builtins/fp_lib.h @@ -26,18 +26,6 @@ #include #include -// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in -// 32-bit mode. -#if defined(__FreeBSD__) && defined(__i386__) -#include -#if __FreeBSD_version < 903000 // v9.3 -#define uint64_t unsigned long long -#define int64_t long long -#undef UINT64_C -#define UINT64_C(c) (c##ULL) -#endif -#endif - #if defined SINGLE_PRECISION typedef uint16_t half_rep_t; diff --git a/compiler-rt/lib/builtins/int_types.h b/compiler-rt/lib/builtins/int_types.h index 18bf0a7f3bf993979c0ff5337ae78debb8d020f4..7624c728061518155461fb53914665b179ffb169 100644 --- a/compiler-rt/lib/builtins/int_types.h +++ b/compiler-rt/lib/builtins/int_types.h @@ -139,7 +139,6 @@ typedef union { udwords u; double f; } double_bits; -#endif typedef struct { #if _YUGA_LITTLE_ENDIAN @@ -220,7 +219,6 @@ typedef union { #define CRT_HAS_TF_MODE #endif -#if CRT_HAS_FLOATING_POINT #if __STDC_VERSION__ >= 199901L typedef float _Complex Fcomplex; typedef double _Complex Dcomplex; @@ -270,5 +268,5 @@ typedef struct { #define COMPLEXTF_IMAGINARY(x) (x).imaginary #endif -#endif +#endif // CRT_HAS_FLOATING_POINT #endif // INT_TYPES_H diff --git a/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.cpp b/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.cpp index 9ec598bf2ce9e418e53277e6f74b13b0350ec924..f95194d19f03a42a88696827cfa8c9bb23b7b28c 100644 --- a/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.cpp +++ b/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.cpp @@ -19,4 +19,10 @@ static ChainedOriginDepot chainedOriginDepot; ChainedOriginDepot* GetChainedOriginDepot() { return &chainedOriginDepot; } +void ChainedOriginDepotLockBeforeFork() { chainedOriginDepot.LockBeforeFork(); } + +void ChainedOriginDepotUnlockAfterFork(bool fork_child) { + chainedOriginDepot.UnlockAfterFork(fork_child); +} + } // namespace __dfsan diff --git a/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.h b/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.h index d715ef707f41b7b35f1bc02073efa31d0bf3e291..83b9e29e1b710d4cd042553dbbf1515ae8a312dc 100644 --- a/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.h +++ b/compiler-rt/lib/dfsan/dfsan_chained_origin_depot.h @@ -21,6 +21,9 @@ namespace __dfsan { ChainedOriginDepot* GetChainedOriginDepot(); +void ChainedOriginDepotLockBeforeFork(); +void ChainedOriginDepotUnlockAfterFork(bool fork_child); + } // namespace __dfsan #endif // DFSAN_CHAINED_ORIGIN_DEPOT_H diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp index 38371d353368183ab3cd3250ecb51db35924c82c..05b48fd0525e33509af8a1acf4edea7307426bd3 100644 --- a/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -2893,13 +2893,13 @@ int __dfso___isoc99_sscanf(char *str, const char *format, dfsan_label str_label, } static void BeforeFork() { - StackDepotLockAll(); - GetChainedOriginDepot()->LockAll(); + StackDepotLockBeforeFork(); + ChainedOriginDepotLockBeforeFork(); } -static void AfterFork() { - GetChainedOriginDepot()->UnlockAll(); - StackDepotUnlockAll(); +static void AfterFork(bool fork_child) { + ChainedOriginDepotUnlockAfterFork(fork_child); + StackDepotUnlockAfterFork(fork_child); } SANITIZER_INTERFACE_ATTRIBUTE @@ -2913,7 +2913,7 @@ SANITIZER_INTERFACE_ATTRIBUTE pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) { BeforeFork(); pid_t pid = __dfsw_fork(ret_label); - AfterFork(); + AfterFork(/* fork_child= */ pid == 0); return pid; } diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index 2f6cb10caf1be602b8aad0fb985a056e7bd6b067..52780becbdb264394b6bbc04a607b93b361bb752 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -678,6 +678,8 @@ uptr __hwasan_tag_pointer(uptr p, u8 tag) { return AddTagToPointer(p, tag); } +u8 __hwasan_get_tag_from_pointer(uptr p) { return GetTagFromPointer(p); } + void __hwasan_handle_longjmp(const void *sp_dst) { uptr dst = (uptr)sp_dst; // HWASan does not support tagged SP. diff --git a/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h index 37ef482228511064d1e16ea8bd6055e2f0f5d582..df21375e81671fb13165f7334da1e428db9cc284 100644 --- a/compiler-rt/lib/hwasan/hwasan.h +++ b/compiler-rt/lib/hwasan/hwasan.h @@ -104,9 +104,9 @@ static inline void *UntagPtr(const void *tagged_ptr) { } static inline uptr AddTagToPointer(uptr p, tag_t tag) { - return InTaggableRegion(p) - ? ((p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift)) - : p; + return InTaggableRegion(p) ? ((p & ~kAddressTagMask) | + ((uptr)(tag & kTagMask) << kAddressTagShift)) + : p; } namespace __hwasan { diff --git a/compiler-rt/lib/hwasan/hwasan_interface_internal.h b/compiler-rt/lib/hwasan/hwasan_interface_internal.h index e7804cc4903343238511e993d4234fa6ffbfa2bc..8f2f77dad917d27fdf77559ac9a4b25e51a42932 100644 --- a/compiler-rt/lib/hwasan/hwasan_interface_internal.h +++ b/compiler-rt/lib/hwasan/hwasan_interface_internal.h @@ -160,6 +160,9 @@ void __hwasan_tag_memory(uptr p, u8 tag, uptr sz); SANITIZER_INTERFACE_ATTRIBUTE uptr __hwasan_tag_pointer(uptr p, u8 tag); +SANITIZER_INTERFACE_ATTRIBUTE +u8 __hwasan_get_tag_from_pointer(uptr p); + SANITIZER_INTERFACE_ATTRIBUTE void __hwasan_tag_mismatch(uptr addr, u8 ts); diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp index f01fa427641347b8a44de7da8260ecaf3b12a80e..e6aa60b324fa7f16b36a65bb8fa961de3dc0fdd7 100644 --- a/compiler-rt/lib/hwasan/hwasan_linux.cpp +++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp @@ -521,16 +521,32 @@ uptr TagMemoryAligned(uptr p, uptr size, tag_t tag) { return AddTagToPointer(p, tag); } +static void BeforeFork() { + if (CAN_SANITIZE_LEAKS) { + __lsan::LockGlobal(); + } + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and lock the + // stuff we need. + __lsan::LockThreads(); + __lsan::LockAllocator(); + StackDepotLockBeforeFork(); +} + +static void AfterFork(bool fork_child) { + StackDepotUnlockAfterFork(fork_child); + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and unlock + // the stuff we need. + __lsan::UnlockAllocator(); + __lsan::UnlockThreads(); + if (CAN_SANITIZE_LEAKS) { + __lsan::UnlockGlobal(); + } +} + void HwasanInstallAtForkHandler() { - auto before = []() { - HwasanAllocatorLock(); - StackDepotLockAll(); - }; - auto after = []() { - StackDepotUnlockAll(); - HwasanAllocatorUnlock(); - }; - pthread_atfork(before, after, after); + pthread_atfork( + &BeforeFork, []() { AfterFork(/* fork_child= */ false); }, + []() { AfterFork(/* fork_child= */ true); }); } void InstallAtExitCheckLeaks() { diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp index 5e8aa315801bcdfb9a7f2ae2676004361976c6ab..1a018a891b56ee15f825f08631409d0f7b4e77b7 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -205,6 +205,7 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa, tag_t addr_tag, uptr untagged_addr) { uptr frames = Min((uptr)flags()->stack_history_size, sa->size()); bool found_local = false; + InternalScopedString location; for (uptr i = 0; i < frames; i++) { const uptr *record_addr = &(*sa)[i]; uptr record = *record_addr; @@ -220,24 +221,56 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa, for (LocalInfo &local : frame.locals) { if (!local.has_frame_offset || !local.has_size || !local.has_tag_offset) continue; + if (!(local.name && internal_strlen(local.name)) && + !(local.function_name && internal_strlen(local.name)) && + !(local.decl_file && internal_strlen(local.decl_file))) + continue; tag_t obj_tag = base_tag ^ local.tag_offset; if (obj_tag != addr_tag) continue; - // Calculate the offset from the object address to the faulting - // address. Because we only store bits 4-19 of FP (bits 0-3 are - // guaranteed to be zero), the calculation is performed mod 2^20 and may - // harmlessly underflow if the address mod 2^20 is below the object - // address. - uptr obj_offset = - (untagged_addr - fp - local.frame_offset) & (kRecordFPModulus - 1); - if (obj_offset >= local.size) - continue; + // Guess top bits of local variable from the faulting address, because + // we only store bits 4-19 of FP (bits 0-3 are guaranteed to be zero). + uptr local_beg = (fp + local.frame_offset) | + (untagged_addr & ~(uptr(kRecordFPModulus) - 1)); + uptr local_end = local_beg + local.size; + if (!found_local) { - Printf("Potentially referenced stack objects:\n"); + Printf("\nPotentially referenced stack objects:\n"); found_local = true; } - Printf(" %s in %s %s:%d\n", local.name, local.function_name, - local.decl_file, local.decl_line); + + uptr offset; + const char *whence; + const char *cause; + if (local_beg <= untagged_addr && untagged_addr < local_end) { + offset = untagged_addr - local_beg; + whence = "inside"; + cause = "use-after-scope"; + } else if (untagged_addr >= local_end) { + offset = untagged_addr - local_end; + whence = "after"; + cause = "stack-buffer-overflow"; + } else { + offset = local_beg - untagged_addr; + whence = "before"; + cause = "stack-buffer-overflow"; + } + Decorator d; + Printf("%s", d.Error()); + Printf("Cause: %s\n", cause); + Printf("%s", d.Default()); + Printf("%s", d.Location()); + StackTracePrinter::GetOrInit()->RenderSourceLocation( + &location, local.decl_file, local.decl_line, /* column= */ 0, + common_flags()->symbolize_vs_style, + common_flags()->strip_path_prefix); + Printf( + "%p is located %zd bytes %s a %zd-byte local variable %s [%p,%p) " + "in %s %s\n", + untagged_addr, offset, whence, local_end - local_beg, local.name, + local_beg, local_end, local.function_name, location.data()); + location.clear(); + Printf("%s\n", d.Default()); } frame.Clear(); } @@ -363,7 +396,7 @@ static void PrintTagsAroundAddr(uptr addr, GetTag get_tag, InternalScopedString s; addr = MemToShadow(addr); s.AppendF( - "Memory tags around the buggy address (one tag corresponds to %zd " + "\nMemory tags around the buggy address (one tag corresponds to %zd " "bytes):\n", kShadowAlignment); PrintTagInfoAroundAddr(addr, kShadowLines, s, @@ -745,8 +778,6 @@ void BaseReport::PrintAddressDescription() const { // Check stack first. If the address is on the stack of a live thread, we // know it cannot be a heap / global overflow. for (const auto &sa : allocations.stack) { - // TODO(fmayer): figure out how to distinguish use-after-return and - // stack-buffer-overflow. Printf("%s", d.Error()); Printf("\nCause: stack tag-mismatch\n"); Printf("%s", d.Location()); @@ -803,8 +834,10 @@ void BaseReport::PrintAddressDescription() const { } // Print the remaining threads, as an extra information, 1 line per thread. - if (flags()->print_live_threads_info) + if (flags()->print_live_threads_info) { + Printf("\n"); hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { t->Announce(); }); + } if (!num_descriptions_printed) // We exhausted our possibilities. Bail out. @@ -1020,7 +1053,7 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size, // See the frame breakdown defined in __hwasan_tag_mismatch (from // hwasan_tag_mismatch_{aarch64,riscv64}.S). void ReportRegisters(const uptr *frame, uptr pc) { - Printf("Registers where the failure occurred (pc %p):\n", pc); + Printf("\nRegisters where the failure occurred (pc %p):\n", pc); // We explicitly print a single line (4 registers/line) each iteration to // reduce the amount of logcat error messages printed. Each Printf() will diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index ce36547580e6e60ccdaaa6bfb697d50c47ebac22..3e14a718513d7f3d1c26cb2a59bfd6168a16930c 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -68,6 +68,7 @@ void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size, } Print("Creating : "); } + ClearShadowForThreadStackAndTLS(); } void Thread::InitStackRingBuffer(uptr stack_buffer_start, diff --git a/compiler-rt/lib/lsan/lsan.cpp b/compiler-rt/lib/lsan/lsan.cpp index 6b223603c6a79c4f5c1645386f3ad98edadc6946..7a27b600f203f7f9e397cfebd7b69c302956c8cf 100644 --- a/compiler-rt/lib/lsan/lsan.cpp +++ b/compiler-rt/lib/lsan/lsan.cpp @@ -101,6 +101,7 @@ extern "C" void __lsan_init() { InstallDeadlySignalHandlers(LsanOnDeadlySignal); InitializeMainThread(); InstallAtExitCheckLeaks(); + InstallAtForkHandler(); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); diff --git a/compiler-rt/lib/lsan/lsan.h b/compiler-rt/lib/lsan/lsan.h index 757edec8e104f906206520ce6207d99b6a02cd06..0074ad5308785cf875f2dde66c5269f1e0612dac 100644 --- a/compiler-rt/lib/lsan/lsan.h +++ b/compiler-rt/lib/lsan/lsan.h @@ -40,6 +40,7 @@ void InitializeInterceptors(); void ReplaceSystemMalloc(); void LsanOnDeadlySignal(int signo, void *siginfo, void *context); void InstallAtExitCheckLeaks(); +void InstallAtForkHandler(); #define ENSURE_LSAN_INITED \ do { \ diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index 8b1af5b629fbce10edbaaf7e23092b4d324a1757..e24839c984b346e087a511d4c1311acfa5a3e20d 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -42,6 +42,9 @@ namespace __lsan { // also to protect the global list of root regions. static Mutex global_mutex; +void LockGlobal() SANITIZER_ACQUIRE(global_mutex) { global_mutex.Lock(); } +void UnlockGlobal() SANITIZER_RELEASE(global_mutex) { global_mutex.Unlock(); } + Flags lsan_flags; void DisableCounterUnderflow() { diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index d3e768363e93b96e9162ea2ea165752cd231471e..c598b62105873e36bde865f71f2c510cbbff431b 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -120,6 +120,10 @@ void GetRunningThreadsLocked(InternalMmapVector *threads); void LockAllocator(); void UnlockAllocator(); +// Lock/unlock global mutext. +void LockGlobal(); +void UnlockGlobal(); + // Returns the address range occupied by the global allocator object. void GetAllocatorGlobalRange(uptr *begin, uptr *end); // If p points into a chunk that has been allocated to the user, returns its diff --git a/compiler-rt/lib/lsan/lsan_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_fuchsia.cpp index 4edac9757a9c4927649acd1e15ecf8f664566aa0..ba59bc9b71e3325d28802ef262b55ae1fb14a1cd 100644 --- a/compiler-rt/lib/lsan/lsan_fuchsia.cpp +++ b/compiler-rt/lib/lsan/lsan_fuchsia.cpp @@ -80,6 +80,7 @@ void GetAllThreadAllocatorCachesLocked(InternalMmapVector *caches) { // On Fuchsia, leak detection is done by a special hook after atexit hooks. // So this doesn't install any atexit hook like on other platforms. void InstallAtExitCheckLeaks() {} +void InstallAtForkHandler() {} // ASan defines this to check its `halt_on_error` flag. bool UseExitcodeOnLeak() { return true; } diff --git a/compiler-rt/lib/lsan/lsan_posix.cpp b/compiler-rt/lib/lsan/lsan_posix.cpp index d99e1cc0105ef768487d44e3ef6c954be358452a..422c29acca69f3085e591848db72c05fae1b106d 100644 --- a/compiler-rt/lib/lsan/lsan_posix.cpp +++ b/compiler-rt/lib/lsan/lsan_posix.cpp @@ -14,11 +14,13 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_POSIX -#include "lsan.h" -#include "lsan_allocator.h" -#include "lsan_thread.h" -#include "sanitizer_common/sanitizer_stacktrace.h" -#include "sanitizer_common/sanitizer_tls_get_addr.h" +# include + +# include "lsan.h" +# include "lsan_allocator.h" +# include "lsan_thread.h" +# include "sanitizer_common/sanitizer_stacktrace.h" +# include "sanitizer_common/sanitizer_tls_get_addr.h" namespace __lsan { @@ -98,6 +100,29 @@ void InstallAtExitCheckLeaks() { Atexit(DoLeakCheck); } +static void BeforeFork() { + LockGlobal(); + LockThreads(); + LockAllocator(); + StackDepotLockBeforeFork(); +} + +static void AfterFork(bool fork_child) { + StackDepotUnlockAfterFork(fork_child); + UnlockAllocator(); + UnlockThreads(); + UnlockGlobal(); +} + +void InstallAtForkHandler() { +# if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE + return; // FIXME: Implement FutexWait. +# endif + pthread_atfork( + &BeforeFork, []() { AfterFork(/* fork_child= */ false); }, + []() { AfterFork(/* fork_child= */ true); }); +} + } // namespace __lsan #endif // SANITIZER_POSIX diff --git a/compiler-rt/lib/memprof/memprof_linux.cpp b/compiler-rt/lib/memprof/memprof_linux.cpp index fcd927023f5c3de979d1a8e87ab00dc599e021ac..fcb6f662a82e56506bef5b2f243d93d2235b8324 100644 --- a/compiler-rt/lib/memprof/memprof_linux.cpp +++ b/compiler-rt/lib/memprof/memprof_linux.cpp @@ -20,7 +20,6 @@ #include "memprof_internal.h" #include "memprof_thread.h" #include "sanitizer_common/sanitizer_flags.h" -#include "sanitizer_common/sanitizer_freebsd.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" diff --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp index c4f47dea1104321198fab79f4e6d5a47d5bd0732..3cdf10c149902c276282ff684fb1e864290dd3bd 100644 --- a/compiler-rt/lib/msan/msan.cpp +++ b/compiler-rt/lib/msan/msan.cpp @@ -449,6 +449,7 @@ void __msan_init() { __sanitizer_set_report_path(common_flags()->log_path); InitializeInterceptors(); + InstallAtForkHandler(); CheckASLR(); InitTlsSize(); InstallDeadlySignalHandlers(MsanOnDeadlySignal); diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index b3a9c641b4fb298c7ed60488081b46ddbe560657..25fa2212bdadd31769a697ea1d5d8b55e2ed9287 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -336,6 +336,8 @@ void *MsanTSDGet(); void MsanTSDSet(void *tsd); void MsanTSDDtor(void *tsd); +void InstallAtForkHandler(); + } // namespace __msan #endif // MSAN_H diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index c3b0f8512e82d83755ddff431980a9e7db520a0d..72a7f980d39fb03c6a5148adcccfab1855621d72 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -159,6 +159,10 @@ void MsanAllocatorInit() { max_malloc_size = kMaxAllowedMallocSize; } +void LockAllocator() { allocator.ForceLock(); } + +void UnlockAllocator() { allocator.ForceUnlock(); } + AllocatorCache *GetAllocatorCache(MsanThreadLocalMallocStorage *ms) { CHECK(ms); CHECK_LE(sizeof(AllocatorCache), sizeof(ms->allocator_cache)); diff --git a/compiler-rt/lib/msan/msan_allocator.h b/compiler-rt/lib/msan/msan_allocator.h index 364331d964068e562379a141833955eb2915fe16..c2a38a401f3b6b02383db3da5045899b3557418c 100644 --- a/compiler-rt/lib/msan/msan_allocator.h +++ b/compiler-rt/lib/msan/msan_allocator.h @@ -28,5 +28,8 @@ struct MsanThreadLocalMallocStorage { MsanThreadLocalMallocStorage() {} }; +void LockAllocator(); +void UnlockAllocator(); + } // namespace __msan #endif // MSAN_ALLOCATOR_H diff --git a/compiler-rt/lib/msan/msan_chained_origin_depot.cpp b/compiler-rt/lib/msan/msan_chained_origin_depot.cpp index 49b14131a89be0ad51a73583155f0edb9e982922..b98b0e6b14b58121213dc61b6c5285109504fb16 100644 --- a/compiler-rt/lib/msan/msan_chained_origin_depot.cpp +++ b/compiler-rt/lib/msan/msan_chained_origin_depot.cpp @@ -31,12 +31,10 @@ u32 ChainedOriginDepotGet(u32 id, u32 *other) { return chainedOriginDepot.Get(id, other); } -void ChainedOriginDepotLockAll() { - chainedOriginDepot.LockAll(); -} +void ChainedOriginDepotBeforeFork() { chainedOriginDepot.LockBeforeFork(); } -void ChainedOriginDepotUnlockAll() { - chainedOriginDepot.UnlockAll(); +void ChainedOriginDepotAfterFork(bool fork_child) { + chainedOriginDepot.UnlockAfterFork(fork_child); } } // namespace __msan diff --git a/compiler-rt/lib/msan/msan_chained_origin_depot.h b/compiler-rt/lib/msan/msan_chained_origin_depot.h index ea51c77a905b5d178843eb10f64f73f517f1c915..7518745dc8520a95655b2bf5a153bcf2006b18fd 100644 --- a/compiler-rt/lib/msan/msan_chained_origin_depot.h +++ b/compiler-rt/lib/msan/msan_chained_origin_depot.h @@ -30,8 +30,8 @@ bool ChainedOriginDepotPut(u32 here_id, u32 prev_id, u32 *new_id); // Retrieves the stored StackDepot ID for the given origin ID. u32 ChainedOriginDepotGet(u32 id, u32 *other); -void ChainedOriginDepotLockAll(); -void ChainedOriginDepotUnlockAll(); +void ChainedOriginDepotBeforeFork(); +void ChainedOriginDepotAfterFork(bool fork_child); } // namespace __msan diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index c2d740e7762b4bfdb0e012e340384667f606e229..2c9f2c01e14b061be12e4effabfeb266d91bc875 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -1326,24 +1326,6 @@ static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) { return res; } -static void BeforeFork() { - StackDepotLockAll(); - ChainedOriginDepotLockAll(); -} - -static void AfterFork() { - ChainedOriginDepotUnlockAll(); - StackDepotUnlockAll(); -} - -INTERCEPTOR(int, fork, void) { - ENSURE_MSAN_INITED(); - BeforeFork(); - int pid = REAL(fork)(); - AfterFork(); - return pid; -} - // NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly // with MSan. #if SANITIZER_LINUX @@ -1933,7 +1915,6 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(atexit); INTERCEPT_FUNCTION(__cxa_atexit); INTERCEPT_FUNCTION(shmat); - INTERCEPT_FUNCTION(fork); MSAN_MAYBE_INTERCEPT_OPENPTY; MSAN_MAYBE_INTERCEPT_FORKPTY; diff --git a/compiler-rt/lib/msan/msan_linux.cpp b/compiler-rt/lib/msan/msan_linux.cpp index bced00ba242822414018b39859c92dcbf4406ce6..c7ecb7cad56661901df0d9a30ba3bbf49b0cba3b 100644 --- a/compiler-rt/lib/msan/msan_linux.cpp +++ b/compiler-rt/lib/msan/msan_linux.cpp @@ -14,23 +14,25 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD -#include "msan.h" -#include "msan_report.h" -#include "msan_thread.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sanitizer_common/sanitizer_common.h" -#include "sanitizer_common/sanitizer_procmaps.h" +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include "msan.h" +# include "msan_allocator.h" +# include "msan_chained_origin_depot.h" +# include "msan_report.h" +# include "msan_thread.h" +# include "sanitizer_common/sanitizer_common.h" +# include "sanitizer_common/sanitizer_procmaps.h" +# include "sanitizer_common/sanitizer_stackdepot.h" namespace __msan { @@ -254,7 +256,27 @@ void MsanTSDDtor(void *tsd) { atomic_signal_fence(memory_order_seq_cst); MsanThread::TSDDtor(tsd); } -#endif +# endif + +static void BeforeFork() { + // Usually we lock ThreadRegistry, but msan does not have one. + LockAllocator(); + StackDepotLockBeforeFork(); + ChainedOriginDepotBeforeFork(); +} + +static void AfterFork(bool fork_child) { + ChainedOriginDepotAfterFork(fork_child); + StackDepotUnlockAfterFork(fork_child); + UnlockAllocator(); + // Usually we unlock ThreadRegistry, but msan does not have one. +} + +void InstallAtForkHandler() { + pthread_atfork( + &BeforeFork, []() { AfterFork(/* fork_child= */ false); }, + []() { AfterFork(/* fork_child= */ true); }); +} } // namespace __msan diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp index 9c8ff9d9b8f9d2e648ab53a8c1b8a92c05b4e249..41b99fabe84f4789d3ae179ed3f3bb4aefb812c5 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cpp +++ b/compiler-rt/lib/msan/tests/msan_test.cpp @@ -3241,7 +3241,7 @@ TEST(MemorySanitizer, dlopenFailed) { #endif // MSAN_TEST_DISABLE_DLOPEN -#if !defined(__FreeBSD__) && !defined(__NetBSD__) +#if !defined(__NetBSD__) TEST(MemorySanitizer, sched_getaffinity) { cpu_set_t mask; if (sched_getaffinity(getpid(), sizeof(mask), &mask) == 0) diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp index e3a1cdf3c4fcc334e13f34cb27b41362a0e96336..340846f5f9001774eec24a5fb3b33bc42fecc1f5 100644 --- a/compiler-rt/lib/orc/macho_platform.cpp +++ b/compiler-rt/lib/orc/macho_platform.cpp @@ -825,6 +825,10 @@ void *MachOPlatformRuntimeState::dlsym(void *DSOHandle, const char *Symbol) { return nullptr; } + // Sign callable symbols as functions, to match dyld. + if ((Result.second & MachOExecutorSymbolFlags::Callable) == + MachOExecutorSymbolFlags::Callable) + return reinterpret_cast(Result.first.toPtr()); return Result.first.toPtr(); } diff --git a/compiler-rt/lib/orc/tests/CMakeLists.txt b/compiler-rt/lib/orc/tests/CMakeLists.txt index 6014ed328d2cc84466eef2c573032b33b0142ab2..2f1cb7657c2818b1e6f3290c7caa5c6a53fba187 100644 --- a/compiler-rt/lib/orc/tests/CMakeLists.txt +++ b/compiler-rt/lib/orc/tests/CMakeLists.txt @@ -27,7 +27,9 @@ endfunction() function(get_orc_lib_for_arch arch lib) if(APPLE) - set(tgt_name "RTOrc.test.osx") + if("osx" IN_LIST ORC_SUPPORTED_OS) + set(tgt_name "RTOrc.test.osx") + endif() else() set(tgt_name "RTOrc.test.${arch}") endif() @@ -65,14 +67,16 @@ macro(add_orc_unittest testname) foreach(arch ${ORC_TEST_ARCH}) set(TEST_OBJECTS) get_orc_lib_for_arch(${arch} ORC_RUNTIME_LIBS) - generate_compiler_rt_tests(TEST_OBJECTS - OrcRTUnitTests "${testname}-${arch}-Test" "${arch}" - SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} - RUNTIME "${ORC_RUNTIME_LIBS}" - COMPILE_DEPS ${TEST_HEADERS} ${ORC_HEADERS} - DEPS llvm_gtest ${ORC_DEPS} - CFLAGS ${ORC_UNITTEST_CFLAGS} ${COMPILER_RT_GTEST_CFLAGS} - LINK_FLAGS ${ORC_UNITTEST_LINK_FLAGS}) + if(ORC_RUNTIME_LIBS) + generate_compiler_rt_tests(TEST_OBJECTS + OrcRTUnitTests "${testname}-${arch}-Test" "${arch}" + SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} + RUNTIME "${ORC_RUNTIME_LIBS}" + COMPILE_DEPS ${TEST_HEADERS} ${ORC_HEADERS} + DEPS llvm_gtest ${ORC_DEPS} + CFLAGS ${ORC_UNITTEST_CFLAGS} ${COMPILER_RT_GTEST_CFLAGS} + LINK_FLAGS ${ORC_UNITTEST_LINK_FLAGS}) + endif() endforeach() endif() endmacro() @@ -83,21 +87,25 @@ macro(add_orc_tool toolname) foreach(arch ${ORC_TEST_ARCH}) set(TOOL_OBJECTS) get_orc_lib_for_arch(${arch} ORC_RUNTIME_LIBS) - generate_compiler_rt_tests(TOOL_OBJECTS - OrcRTTools "${toolname}-${arch}" "${arch}" - SOURCES ${TOOL_SOURCES} - RUNTIME "${ORC_RUNTIME_LIBS}" - COMPILE_DEPS ${TOOL_HEADERS} ${ORC_HEADERS} - DEPS ${ORC_DEPS} - CFLAGS ${ORC_UNITTEST_CFLAGS} - LINK_FLAGS ${ORC_UNITTEST_LINK_FLAGS}) + if(ORC_RUNTIME_LIBS) + generate_compiler_rt_tests(TOOL_OBJECTS + OrcRTTools "${toolname}-${arch}" "${arch}" + SOURCES ${TOOL_SOURCES} + RUNTIME "${ORC_RUNTIME_LIBS}" + COMPILE_DEPS ${TOOL_HEADERS} ${ORC_HEADERS} + DEPS ${ORC_DEPS} + CFLAGS ${ORC_UNITTEST_CFLAGS} + LINK_FLAGS ${ORC_UNITTEST_LINK_FLAGS}) + endif() endforeach() endif() endmacro() if (APPLE) - add_orc_lib("RTOrc.test.osx" - $) + if("osx" IN_LIST ORC_SUPPORTED_OS) + add_orc_lib("RTOrc.test.osx" + $) + endif() else() foreach(arch ${ORC_SUPPORTED_ARCH}) add_orc_lib("RTOrc.test.${arch}" diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c b/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c index 9dbd702865fd2906f8c435688e18dc04b13f868b..c976776ae59e9c78fb65b9515c6d2ad9b92e1134 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c @@ -13,13 +13,14 @@ #if defined(_MSC_VER) /* Merge read-write sections into .data. */ -#pragma comment(linker, "/MERGE:.lprfc=.data") #pragma comment(linker, "/MERGE:.lprfb=.data") #pragma comment(linker, "/MERGE:.lprfd=.data") #pragma comment(linker, "/MERGE:.lprfv=.data") #pragma comment(linker, "/MERGE:.lprfnd=.data") /* Do *NOT* merge .lprfn and .lcovmap into .rdata. llvm-cov must be able to find * after the fact. + * Do *NOT* merge .lprfc .rdata. When binary profile correlation is enabled, + * llvm-cov must be able to find after the fact. */ /* Allocate read-only section bounds. */ @@ -73,7 +74,17 @@ ValueProfNode *__llvm_profile_end_vnodes(void) { return &VNodesEnd; } ValueProfNode *CurrentVNode = &VNodesStart + 1; ValueProfNode *EndVNode = &VNodesEnd; +/* lld-link provides __buildid symbol which ponits to the 16 bytes build id when + * using /build-id flag. https://lld.llvm.org/windows_support.html#lld-flags */ +#define BUILD_ID_LEN 16 +COMPILER_RT_WEAK extern uint8_t __buildid[BUILD_ID_LEN]; COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { + if (*__buildid) { + if (Writer && + lprofWriteOneBinaryId(Writer, BUILD_ID_LEN, __buildid, 0) == -1) + return -1; + return sizeof(uint64_t) + BUILD_ID_LEN; + } return 0; } diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index fb7584c298a1c947c0e58f173ca1fcca1c6127bc..f762524c333acf27624bc349b8d8e77ee8f0d5f6 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -151,7 +151,6 @@ set(SANITIZER_IMPL_HEADERS sanitizer_flags.h sanitizer_flags.inc sanitizer_flat_map.h - sanitizer_freebsd.h sanitizer_fuchsia.h sanitizer_getauxval.h sanitizer_hash.h diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp index e0e2bd01069f24a27e7697125cfc9e8178e3992b..df2b2eb23df28e6b6d0d08edc6bedb40e6722d60 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp @@ -139,9 +139,11 @@ u32 ChainedOriginDepot::Get(u32 id, u32 *other) { return desc.here_id; } -void ChainedOriginDepot::LockAll() { depot.LockAll(); } +void ChainedOriginDepot::LockBeforeFork() { depot.LockBeforeFork(); } -void ChainedOriginDepot::UnlockAll() { depot.UnlockAll(); } +void ChainedOriginDepot::UnlockAfterFork(bool fork_child) { + depot.UnlockAfterFork(fork_child); +} void ChainedOriginDepot::TestOnlyUnmap() { depot.TestOnlyUnmap(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h b/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h index f9f192b685719eae17a4a1bc7a5a5226bf0d1479..f3da28129e6bd8b66302c220ccaa64b8c0feb2d9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h @@ -32,8 +32,8 @@ class ChainedOriginDepot { // Retrieves the stored StackDepot ID for the given origin ID. u32 Get(u32 id, u32 *other); - void LockAll(); - void UnlockAll(); + void LockBeforeFork(); + void UnlockAfterFork(bool fork_child); void TestOnlyUnmap(); private: diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index ba46707516971f964f8ec98f82638af5ec4f29b0..77fa1b4965a7a4b07a97ef004d24a05cca8314c3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -6785,7 +6785,7 @@ INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags, #endif #if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE -INTERCEPTOR(int, eventfd_read, int fd, u64 *value) { +INTERCEPTOR(int, eventfd_read, int fd, __sanitizer_eventfd_t *value) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); @@ -6796,7 +6796,7 @@ INTERCEPTOR(int, eventfd_read, int fd, u64 *value) { } return res; } -INTERCEPTOR(int, eventfd_write, int fd, u64 value) { +INTERCEPTOR(int, eventfd_write, int fd, __sanitizer_eventfd_t value) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value); if (fd >= 0) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h b/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h index 8bb8304910c73f0f57590a860c28d74f878f8684..d246781fe1df5e22feacb0d3bf213771b8d2e68b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h @@ -109,6 +109,10 @@ class TwoLevelMap { return *AddressSpaceView::LoadWritable(&map2[idx % kSize2]); } + void Lock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { mu_.Lock(); } + + void Unlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { mu_.Unlock(); } + private: constexpr uptr MmapSize() const { return RoundUpTo(kSize2 * sizeof(T), GetPageSizeCached()); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h deleted file mode 100644 index 82b227eab6dab73dbce734891a4a138dcb94da99..0000000000000000000000000000000000000000 --- a/compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h +++ /dev/null @@ -1,137 +0,0 @@ -//===-- sanitizer_freebsd.h -------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file is a part of Sanitizer runtime. It contains FreeBSD-specific -// definitions. -// -//===----------------------------------------------------------------------===// - -#ifndef SANITIZER_FREEBSD_H -#define SANITIZER_FREEBSD_H - -#include "sanitizer_internal_defs.h" - -// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in -// 32-bit mode. -#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) -#include -#if __FreeBSD_version <= 902001 // v9.2 -#include -#include -#include - -namespace __sanitizer { - -typedef unsigned long long __xuint64_t; - -typedef __int32_t __xregister_t; - -typedef struct __xmcontext { - __xregister_t mc_onstack; - __xregister_t mc_gs; - __xregister_t mc_fs; - __xregister_t mc_es; - __xregister_t mc_ds; - __xregister_t mc_edi; - __xregister_t mc_esi; - __xregister_t mc_ebp; - __xregister_t mc_isp; - __xregister_t mc_ebx; - __xregister_t mc_edx; - __xregister_t mc_ecx; - __xregister_t mc_eax; - __xregister_t mc_trapno; - __xregister_t mc_err; - __xregister_t mc_eip; - __xregister_t mc_cs; - __xregister_t mc_eflags; - __xregister_t mc_esp; - __xregister_t mc_ss; - - int mc_len; - int mc_fpformat; - int mc_ownedfp; - __xregister_t mc_flags; - - int mc_fpstate[128] __aligned(16); - __xregister_t mc_fsbase; - __xregister_t mc_gsbase; - __xregister_t mc_xfpustate; - __xregister_t mc_xfpustate_len; - - int mc_spare2[4]; -} xmcontext_t; - -typedef struct __xucontext { - sigset_t uc_sigmask; - xmcontext_t uc_mcontext; - - struct __ucontext *uc_link; - stack_t uc_stack; - int uc_flags; - int __spare__[4]; -} xucontext_t; - -struct xkinfo_vmentry { - int kve_structsize; - int kve_type; - __xuint64_t kve_start; - __xuint64_t kve_end; - __xuint64_t kve_offset; - __xuint64_t kve_vn_fileid; - __uint32_t kve_vn_fsid; - int kve_flags; - int kve_resident; - int kve_private_resident; - int kve_protection; - int kve_ref_count; - int kve_shadow_count; - int kve_vn_type; - __xuint64_t kve_vn_size; - __uint32_t kve_vn_rdev; - __uint16_t kve_vn_mode; - __uint16_t kve_status; - int _kve_ispare[12]; - char kve_path[PATH_MAX]; -}; - -typedef struct { - __uint32_t p_type; - __uint32_t p_offset; - __uint32_t p_vaddr; - __uint32_t p_paddr; - __uint32_t p_filesz; - __uint32_t p_memsz; - __uint32_t p_flags; - __uint32_t p_align; -} XElf32_Phdr; - -struct xdl_phdr_info { - Elf_Addr dlpi_addr; - const char *dlpi_name; - const XElf32_Phdr *dlpi_phdr; - Elf_Half dlpi_phnum; - unsigned long long int dlpi_adds; - unsigned long long int dlpi_subs; - size_t dlpi_tls_modid; - void *dlpi_tls_data; -}; - -typedef int (*__xdl_iterate_hdr_callback)(struct xdl_phdr_info *, size_t, - void *); -typedef int xdl_iterate_phdr_t(__xdl_iterate_hdr_callback, void *); - -#define xdl_iterate_phdr(callback, param) \ - (((xdl_iterate_phdr_t *)dl_iterate_phdr)((callback), (param))) - -} // namespace __sanitizer - -#endif // __FreeBSD_version <= 902001 -#endif // SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) - -#endif // SANITIZER_FREEBSD_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 841d7c09629247226fba7c0183ee96f0000a84fd..5d2dd3a7a658fe07f7594898c909b1eb5874d96c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -58,7 +58,6 @@ # include # include # include -# include # if !SANITIZER_SOLARIS # include # endif @@ -136,9 +135,7 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0 # endif -// Note : FreeBSD had implemented both -// Linux apis, available from -// future 12.x version most likely +// Note : FreeBSD implemented both Linux and OpenBSD apis. # if SANITIZER_LINUX && defined(__NR_getrandom) # if !defined(GRND_NONBLOCK) # define GRND_NONBLOCK 1 @@ -148,10 +145,8 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; # define SANITIZER_USE_GETRANDOM 0 # endif // SANITIZER_LINUX && defined(__NR_getrandom) -# if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000 +# if SANITIZER_FREEBSD # define SANITIZER_USE_GETENTROPY 1 -# else -# define SANITIZER_USE_GETENTROPY 0 # endif namespace __sanitizer { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 8e942b69e6a7beb843e66e4126c673ca6a3e288a..cccbb4d256df2f64d6fc6f0f8906f2e35625bc78 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -21,7 +21,6 @@ # include "sanitizer_common.h" # include "sanitizer_file.h" # include "sanitizer_flags.h" -# include "sanitizer_freebsd.h" # include "sanitizer_getauxval.h" # include "sanitizer_glibc_version.h" # include "sanitizer_linux.h" @@ -46,7 +45,6 @@ # endif # if SANITIZER_FREEBSD -# include # include # include # include @@ -629,11 +627,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, # if !SANITIZER_FREEBSD typedef ElfW(Phdr) Elf_Phdr; -# elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2 -# define Elf_Phdr XElf32_Phdr -# define dl_phdr_info xdl_phdr_info -# define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b)) -# endif // !SANITIZER_FREEBSD +# endif struct DlIteratePhdrData { InternalMmapVectorNoCtor *modules; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 8c7c00de6d1292f79bd63a41e024701b4c7285af..289ae661c343f15b9ddc929faf5e94aed5289e16 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -301,7 +301,8 @@ #define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME (SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_CONFSTR \ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) -#define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_SCHED_GETAFFINITY \ + (SI_LINUX_NOT_ANDROID || SI_FREEBSD) #define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRERROR SI_POSIX #define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX @@ -462,7 +463,7 @@ (SI_LINUX || SI_MAC || SI_WINDOWS || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_RECV_RECVFROM SI_POSIX #define SANITIZER_INTERCEPT_SEND_SENDTO SI_POSIX -#define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX +#define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE (SI_LINUX || SI_FREEBSD) #define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33)) #define SANITIZER_INTERCEPT_STAT \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h index b119f059007d841ccacde49f9284e56723e04c9c..43b8a38f39be1827703fd3afd76495162c848714 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -726,6 +726,8 @@ struct __sanitizer_cpuset { typedef struct __sanitizer_cpuset __sanitizer_cpuset_t; extern unsigned struct_cpuset_sz; + +typedef unsigned long long __sanitizer_eventfd_t; } // namespace __sanitizer # define CHECK_TYPE_SIZE(TYPE) \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 58244c9944a03a993b028bb449ce0ca3f158d6da..1ee26e0cbbb99921734da17d7ba047e83f8868b6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -938,6 +938,8 @@ struct __sanitizer_cookie_io_functions_t { __sanitizer_cookie_io_seek seek; __sanitizer_cookie_io_close close; }; + +typedef unsigned long long __sanitizer_eventfd_t; #endif #define IOC_NRBITS 8 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp index 36a82c4ac966ba9e367d5255a030c943894f22aa..dcfd94fe3225cd9e695497809b5a72b30888ccf9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp @@ -13,9 +13,6 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_NETBSD #include "sanitizer_common.h" -#if SANITIZER_FREEBSD -#include "sanitizer_freebsd.h" -#endif #include "sanitizer_procmaps.h" // clang-format off @@ -29,14 +26,6 @@ #include -// Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode. -#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) -#include -#if __FreeBSD_version <= 902001 // v9.2 -#define kinfo_vmentry xkinfo_vmentry -#endif -#endif - namespace __sanitizer { #if SANITIZER_FREEBSD diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp index 148470943b47b3503c071d7342e8dbf531e5effb..c11df0ddfde438bd429cc39d7bcef795dc0cd63b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp @@ -44,6 +44,9 @@ StackStore::Id StackStore::Store(const StackTrace &trace, uptr *pack) { uptr idx = 0; *pack = 0; uptr *stack_trace = Alloc(h.size + 1, &idx, pack); + // No more space. + if (stack_trace == nullptr) + return 0; *stack_trace = h.ToUptr(); internal_memcpy(stack_trace + 1, trace.trace, h.size * sizeof(uptr)); *pack += blocks_[GetBlockIdx(idx)].Stored(h.size + 1); @@ -76,8 +79,10 @@ uptr *StackStore::Alloc(uptr count, uptr *idx, uptr *pack) { uptr block_idx = GetBlockIdx(start); uptr last_idx = GetBlockIdx(start + count - 1); if (LIKELY(block_idx == last_idx)) { - // Fits into the a single block. - CHECK_LT(block_idx, ARRAY_SIZE(blocks_)); + // Fits into a single block. + // No more available blocks. Indicate inability to allocate more memory. + if (block_idx >= ARRAY_SIZE(blocks_)) + return nullptr; *idx = start; return blocks_[block_idx].GetOrCreate(this) + GetInBlockIdx(start); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index a746d4621936c62555caa89efcf533804f4716d7..3776e8c97057ebdf4b7d168fbb96228f1e949707 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -215,16 +215,16 @@ StackTrace StackDepotGet(u32 id) { return theDepot.Get(id); } -void StackDepotLockAll() { - theDepot.LockAll(); +void StackDepotLockBeforeFork() { + theDepot.LockBeforeFork(); compress_thread.LockAndStop(); stackStore.LockAll(); } -void StackDepotUnlockAll() { +void StackDepotUnlockAfterFork(bool fork_child) { stackStore.UnlockAll(); compress_thread.Unlock(); - theDepot.UnlockAll(); + theDepot.UnlockAfterFork(fork_child); } void StackDepotPrintAll() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h index cca6fd53468839c63d40e22e7b49ce182406c341..82cf7578d0fb9bd05d460b988447959dbdb008ce 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h @@ -39,8 +39,8 @@ StackDepotHandle StackDepotPut_WithHandle(StackTrace stack); // Retrieves a stored stack trace by the id. StackTrace StackDepotGet(u32 id); -void StackDepotLockAll(); -void StackDepotUnlockAll(); +void StackDepotLockBeforeFork(); +void StackDepotUnlockAfterFork(bool fork_child); void StackDepotPrintAll(); void StackDepotStopBackgroundThread(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h index 96d1ddc87fd032d2a6a5746366e652d7231e8213..279bc5de3bb93bc970f77d719fecf45e082a79e2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h @@ -52,8 +52,8 @@ class StackDepotBase { }; } - void LockAll(); - void UnlockAll(); + void LockBeforeFork(); + void UnlockAfterFork(bool fork_child); void PrintAll(); void TestOnlyUnmap() { @@ -160,18 +160,33 @@ StackDepotBase::Get(u32 id) { } template -void StackDepotBase::LockAll() { - for (int i = 0; i < kTabSize; ++i) { - lock(&tab[i]); - } +void StackDepotBase::LockBeforeFork() { + // Do not lock hash table. It's very expensive, but it's not rely needed. The + // parent process will neither lock nor unlock. Child process risks to be + // deadlocked on already locked buckets. To avoid deadlock we will unlock + // every locked buckets in `UnlockAfterFork`. This may affect consistency of + // the hash table, but the only issue is a few items inserted by parent + // process will be not found by child, and the child may insert them again, + // wasting some space in `stackStore`. + + // We still need to lock nodes. + nodes.Lock(); } template -void StackDepotBase::UnlockAll() { +void StackDepotBase::UnlockAfterFork( + bool fork_child) { + nodes.Unlock(); + + // Only unlock in child process to avoid deadlock. See `LockBeforeFork`. + if (!fork_child) + return; + for (int i = 0; i < kTabSize; ++i) { atomic_uint32_t *p = &tab[i]; uptr s = atomic_load(p, memory_order_relaxed); - unlock(p, s & kUnlockMask); + if (s & kLockMask) + unlock(p, s & kUnlockMask); } } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp index f3818526baab1b7a7efcc56c3d8896845ae7da38..9c8c4bf9d1a4841a67381b11d16951ee8c0da61c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cpp @@ -138,7 +138,10 @@ void SuppressionContext::Parse(const char *str) { } } if (type == suppression_types_num_) { - Printf("%s: failed to parse suppressions\n", SanitizerToolName); + Printf("%s: failed to parse suppressions.\n", SanitizerToolName); + Printf("Supported suppression types are:\n"); + for (type = 0; type < suppression_types_num_; type++) + Printf("- %s\n", suppression_types_[type]); Die(); } Suppression s; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index 28f11352a6b5bbe776add40617a4981400735004..0ddc24802d2167ed6aebea09ffc97c9860b5d044 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -341,15 +341,14 @@ __sanitizer_symbolize_set_inline_frames(bool InlineFrames); class InternalSymbolizer final : public SymbolizerTool { public: static InternalSymbolizer *get(LowLevelAllocator *alloc) { - if (&__sanitizer_symbolize_set_demangle) - CHECK(__sanitizer_symbolize_set_demangle(common_flags()->demangle)); - if (&__sanitizer_symbolize_set_inline_frames) - CHECK(__sanitizer_symbolize_set_inline_frames( - common_flags()->symbolize_inline_frames)); - // These are essential, we don't have InternalSymbolizer without them. - if (&__sanitizer_symbolize_code && &__sanitizer_symbolize_data) - return new (*alloc) InternalSymbolizer(); - return 0; + // These one is the most used one, so we will use it to detect a presence of + // internal symbolizer. + if (&__sanitizer_symbolize_code == nullptr) + return nullptr; + CHECK(__sanitizer_symbolize_set_demangle(common_flags()->demangle)); + CHECK(__sanitizer_symbolize_set_inline_frames( + common_flags()->symbolize_inline_frames)); + return new (*alloc) InternalSymbolizer(); } bool SymbolizePC(uptr addr, SymbolizedStack *stack) override { @@ -371,8 +370,6 @@ class InternalSymbolizer final : public SymbolizerTool { } bool SymbolizeFrame(uptr addr, FrameInfo *info) override { - if (&__sanitizer_symbolize_frame == nullptr) - return false; bool result = __sanitizer_symbolize_frame(info->module, info->module_offset, buffer_, sizeof(buffer_)); if (result) @@ -380,14 +377,10 @@ class InternalSymbolizer final : public SymbolizerTool { return result; } - void Flush() override { - if (&__sanitizer_symbolize_flush) - __sanitizer_symbolize_flush(); - } + void Flush() override { __sanitizer_symbolize_flush(); } const char *Demangle(const char *name) override { - if (&__sanitizer_symbolize_demangle && - __sanitizer_symbolize_demangle(name, buffer_, sizeof(buffer_))) { + if (__sanitizer_symbolize_demangle(name, buffer_, sizeof(buffer_))) { char *res_buff = nullptr; ExtractToken(buffer_, "", &res_buff); return res_buff; diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp index 4bdf75332bf33aa336a7f2591940bc20e226b6ef..c851dbbf2eb233d5d143b792e598608d9399fd82 100644 --- a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp +++ b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp @@ -71,7 +71,7 @@ bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset, auto Printer = std::make_unique( OS, symbolize_error_handler(OS), Config); - // TODO: it is neccessary to set proper SectionIndex here. + // TODO: it is necessary to set proper SectionIndex here. // object::SectionedAddress::UndefSection works for only absolute addresses. if (InlineFrames) { auto ResOrErr = getDefaultSymbolizer()->symbolizeInlinedCode( @@ -103,7 +103,7 @@ bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset, auto Printer = std::make_unique( OS, symbolize_error_handler(OS), Config); - // TODO: it is neccessary to set proper SectionIndex here. + // TODO: it is necessary to set proper SectionIndex here. // object::SectionedAddress::UndefSection works for only absolute addresses. auto ResOrErr = getDefaultSymbolizer()->symbolizeData( ModuleName, @@ -126,7 +126,7 @@ bool __sanitizer_symbolize_frame(const char *ModuleName, uint64_t ModuleOffset, auto Printer = std::make_unique( OS, symbolize_error_handler(OS), Config); - // TODO: it is neccessary to set proper SectionIndex here. + // TODO: it is necessary to set proper SectionIndex here. // object::SectionedAddress::UndefSection works for only absolute addresses. auto ResOrErr = getDefaultSymbolizer()->symbolizeFrame( ModuleName, diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp index 3835ce26c4d54b38758b198e46fdbbcf9ab34fee..479e4a0c184f745fbc4f19205d4201f6b8aa3bfa 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp @@ -148,6 +148,10 @@ static struct StackDepotBenchmarkParams { {500000, 10, 16, true, false}, {1500000, 10, 4, true, true}, {800000, 10, 16, true, true}, + // Go crazy, and create too many unique stacks, such that StackStore runs + // out of space. + {1000000, 1, 128, true, true}, + {100000000, 1, 1, true, true}, }; static std::string PrintStackDepotBenchmarkParams( diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cpp index 50a6ce92f9bedc9bc4ceb454632d92a1744ffdf8..45ed16b173afe47e592697335fa59ad897f6de19 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cpp @@ -130,9 +130,15 @@ TEST_F(SuppressionContextTest, HasSuppressionType) { } TEST_F(SuppressionContextTest, RegressionTestForBufferOverflowInSuppressions) { - EXPECT_DEATH(ctx_.Parse("race"), "failed to parse suppressions"); - EXPECT_DEATH(ctx_.Parse("foo"), "failed to parse suppressions"); + const char *expected_output = + "failed to parse suppressions.\n" + "Supported suppression types are:\n" + "- race\n" + "- thread\n" + "- mutex\n" + "- signal\n"; + EXPECT_DEATH(ctx_.Parse("race"), expected_output); + EXPECT_DEATH(ctx_.Parse("foo"), expected_output); } - } // namespace __sanitizer diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 65ddc488370a7d28b8939bb3301aa286c3491b0e..4624f83d142a0de6bd26661a0b9b7c8919e4fe69 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -939,19 +939,6 @@ public: return RingBufferElements ? ringBufferSizeInBytes(RingBufferElements) : 0; } - static bool setRingBufferSizeForBuffer(char *Buffer, size_t Size) { - // Need at least one entry. - if (Size < sizeof(AllocationRingBuffer) + - sizeof(typename AllocationRingBuffer::Entry)) { - return false; - } - AllocationRingBuffer *RingBuffer = - reinterpret_cast(Buffer); - RingBuffer->Size = (Size - sizeof(AllocationRingBuffer)) / - sizeof(typename AllocationRingBuffer::Entry); - return true; - } - static const uptr MaxTraceSize = 64; static void collectTraceMaybe(const StackDepot *Depot, diff --git a/compiler-rt/lib/scudo/standalone/flags_parser.cpp b/compiler-rt/lib/scudo/standalone/flags_parser.cpp index 6f9b23ea90e23ccf68798d2f25ed5cecc942c4f7..3d8c6f3789b4ccb4707233e1cedbbc284026d956 100644 --- a/compiler-rt/lib/scudo/standalone/flags_parser.cpp +++ b/compiler-rt/lib/scudo/standalone/flags_parser.cpp @@ -10,6 +10,7 @@ #include "common.h" #include "report.h" +#include #include #include #include @@ -143,19 +144,18 @@ bool FlagParser::runHandler(const char *Name, const char *Value, break; case FlagType::FT_int: char *ValueEnd; + errno = 0; long V = strtol(Value, &ValueEnd, 10); - // strtol returns LONG_MAX on overflow and LONG_MIN on underflow. - // This is why we compare-equal here (and lose INT_MIN and INT_MAX as a - // value, but that's okay) - if (V >= INT_MAX || V <= INT_MIN) { + if (errno != 0 || // strtol failed (over or underflow) + V > INT_MAX || V < INT_MIN || // overflows integer + // contains unexpected characters + (*ValueEnd != '"' && *ValueEnd != '\'' && + !isSeparatorOrNull(*ValueEnd))) { reportInvalidFlag("int", Value); - return false; + break; } *reinterpret_cast(Flags[I].Var) = static_cast(V); - Ok = - *ValueEnd == '"' || *ValueEnd == '\'' || isSeparatorOrNull(*ValueEnd); - if (!Ok) - reportInvalidFlag("int", Value); + Ok = true; break; } return Ok; diff --git a/compiler-rt/lib/tsan/go/buildgo.sh b/compiler-rt/lib/tsan/go/buildgo.sh index 0bd59368cc4673682858e36b52e80faf0074aaa0..78ba41a0bdc6d612a9035fbcd86ff2da9a356f61 100755 --- a/compiler-rt/lib/tsan/go/buildgo.sh +++ b/compiler-rt/lib/tsan/go/buildgo.sh @@ -10,6 +10,8 @@ if [ "`uname -a | grep Linux`" != "" ]; then HOST_GOARCH="amd64" elif [ "`uname -a | grep aarch64`" != "" ]; then HOST_GOARCH="arm64" + elif [ "`uname -a | grep loongarch64`" != "" ]; then + HOST_GOARCH="loong64" elif [ "`uname -a | grep -i mips64`" != "" ]; then if [ "`lscpu | grep -i Little`" != "" ]; then HOST_GOARCH="mips64le" diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 80f86ca98ed9cd98804a9ae7ffe09f7b6390bae2..a9f6673ac44e90e3768172a717ae8d95f79f9311 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1380,6 +1380,22 @@ TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) { return res; } +#if SANITIZER_LINUX +TSAN_INTERCEPTOR(int, pthread_mutex_clocklock, void *m, + __sanitizer_clockid_t clock, void *abstime) { + SCOPED_TSAN_INTERCEPTOR(pthread_mutex_clocklock, m, clock, abstime); + MutexPreLock(thr, pc, (uptr)m); + int res = REAL(pthread_mutex_clocklock)(m, clock, abstime); + if (res == errno_EOWNERDEAD) + MutexRepair(thr, pc, (uptr)m); + if (res == 0 || res == errno_EOWNERDEAD) + MutexPostLock(thr, pc, (uptr)m); + if (res == errno_EINVAL) + MutexInvalidAccess(thr, pc, (uptr)m); + return res; +} +#endif + #if SANITIZER_GLIBC # if !__GLIBC_PREREQ(2, 34) // glibc 2.34 applies a non-default version for the two functions. They are no @@ -2902,6 +2918,9 @@ void InitializeInterceptors() { TSAN_INTERCEPT(pthread_mutex_trylock); TSAN_INTERCEPT(pthread_mutex_timedlock); TSAN_INTERCEPT(pthread_mutex_unlock); +#if SANITIZER_LINUX + TSAN_INTERCEPT(pthread_mutex_clocklock); +#endif #if SANITIZER_GLIBC # if !__GLIBC_PREREQ(2, 34) TSAN_INTERCEPT(__pthread_mutex_lock); diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h index 70b9ae09a9904207135e0016c3f9836084586b19..84ff4bfade09ace160aa0312b2362711a5649106 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -622,6 +622,35 @@ struct MappingGoAarch64 { static const uptr kShadowAdd = 0x200000000000ull; }; +/* Go on linux/loongarch64 (47-bit VMA) +0000 0000 1000 - 0000 1000 0000: executable +0000 1000 0000 - 00c0 0000 0000: - +00c0 0000 0000 - 00e0 0000 0000: heap +00e0 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 2800 0000 0000: shadow +2800 0000 0000 - 3000 0000 0000: - +3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects) +3200 0000 0000 - 8000 0000 0000: - +*/ +struct MappingGoLoongArch64_47 { + static const uptr kMetaShadowBeg = 0x300000000000ull; + static const uptr kMetaShadowEnd = 0x320000000000ull; + static const uptr kShadowBeg = 0x200000000000ull; + static const uptr kShadowEnd = 0x280000000000ull; + static const uptr kLoAppMemBeg = 0x000000001000ull; + static const uptr kLoAppMemEnd = 0x00e000000000ull; + static const uptr kMidAppMemBeg = 0; + static const uptr kMidAppMemEnd = 0; + static const uptr kHiAppMemBeg = 0; + static const uptr kHiAppMemEnd = 0; + static const uptr kHeapMemBeg = 0; + static const uptr kHeapMemEnd = 0; + static const uptr kVdsoBeg = 0; + static const uptr kShadowMsk = 0; + static const uptr kShadowXor = 0; + static const uptr kShadowAdd = 0x200000000000ull; +}; + /* Go on linux/mips64 (47-bit VMA) 0000 0000 1000 - 0000 1000 0000: executable @@ -697,6 +726,8 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { return Func::template Apply(arg); # elif defined(__aarch64__) return Func::template Apply(arg); +# elif defined(__loongarch_lp64) + return Func::template Apply(arg); # elif SANITIZER_WINDOWS return Func::template Apply(arg); # else @@ -765,6 +796,7 @@ void ForEachMapping() { Func::template Apply(); Func::template Apply(); Func::template Apply(); + Func::template Apply(); Func::template Apply(); Func::template Apply(); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp index 369509ed0a604ee350baa2568c96baac99c25ae1..b45adea45b27adbe569006f80c69edfb965de601 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp @@ -238,7 +238,13 @@ void InitializePlatformEarly() { Printf("FATAL: Found %zd - Supported 47\n", vmaSize); Die(); } -# endif +# else + if (vmaSize != 47) { + Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); + Printf("FATAL: Found %zd - Supported 47\n", vmaSize); + Die(); + } +# endif #elif defined(__powerpc64__) # if !SANITIZER_GO if (vmaSize != 44 && vmaSize != 46 && vmaSize != 47) { diff --git a/compiler-rt/test/CMakeLists.txt b/compiler-rt/test/CMakeLists.txt index f9b01b15b0e62c6f63ba608260d9af1e87f625e8..7357604b1f651eb59ce2eb03b7c379ca08653294 100644 --- a/compiler-rt/test/CMakeLists.txt +++ b/compiler-rt/test/CMakeLists.txt @@ -37,8 +37,9 @@ if(NOT ANDROID) if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT LLVM_RUNTIMES_BUILD) # Use LLVM utils and Clang from the same build tree. list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS - clang clang-resource-headers FileCheck count not llvm-config llvm-nm llvm-objdump - llvm-readelf llvm-readobj llvm-size llvm-symbolizer compiler-rt-headers sancov split-file) + clang clang-resource-headers FileCheck count not llvm-config llvm-nm + llvm-objdump llvm-readelf llvm-readobj llvm-size llvm-symbolizer + compiler-rt-headers sancov split-file llvm-strip) if (WIN32) list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS KillTheDoctor) endif() diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c index 4e6638be584b0d715185a0fceb495a128fc7a9e9..d390017dd75552859b04f481954a7c3a391d7fcd 100644 --- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c +++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c @@ -36,36 +36,36 @@ int main(int argc, char **argv) { } #endif -// CHECK40: allocated heap chunk; size: 32 offset: 8 -// CHECK40: Cause: heap-buffer-overflow -// CHECK40: is located 10 bytes after a 30-byte region -// -// CHECK80: allocated heap chunk; size: 32 offset: 16 -// CHECK80: Cause: heap-buffer-overflow -// CHECK80: is located 50 bytes after a 30-byte region -// -// CHECKm30: Cause: heap-buffer-overflow -// CHECKm30: is located 30 bytes before a 30-byte region -// -// CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30 -// CHECKMm30: Cause: heap-buffer-overflow -// CHECKMm30: is located 30 bytes before a 1000000-byte region -// -// CHECKM: is a large allocated heap chunk; size: 1003520 offset: 1000000 -// CHECKM: Cause: heap-buffer-overflow -// CHECKM: is located 0 bytes after a 1000000-byte region -// -// CHECK31: tags: [[TAG:..]]/0e([[TAG]]) (ptr/mem) -// CHECK31-NOT: Invalid access starting at offset -// CHECK31: Cause: heap-buffer-overflow -// CHECK31: is located 1 bytes after a 30-byte region -// CHECK31: Memory tags around the buggy address -// CHECK31: [0e] -// CHECK31: Tags for short granules around the buggy address -// CHECK31: {{\[}}[[TAG]]] -// -// CHECK20-NOT: Invalid access starting at offset -// CHECK20: Cause: heap-buffer-overflow -// CHECK20: is located 10 bytes after a 20-byte region [0x{{.*}}0,0x{{.*}}4) + // CHECK40: allocated heap chunk; size: 32 offset: 8 + // CHECK40: Cause: heap-buffer-overflow + // CHECK40: is located 10 bytes after a 30-byte region + // + // CHECK80: allocated heap chunk; size: 32 offset: 16 + // CHECK80: Cause: heap-buffer-overflow + // CHECK80: is located 50 bytes after a 30-byte region + // + // CHECKm30: Cause: heap-buffer-overflow + // CHECKm30: is located 30 bytes before a 30-byte region + // + // CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30 + // CHECKMm30: Cause: heap-buffer-overflow + // CHECKMm30: is located 30 bytes before a 1000000-byte region + // + // CHECKM: is a large allocated heap chunk; size: 1003520 offset: 1000000 + // CHECKM: Cause: heap-buffer-overflow + // CHECKM: is located 0 bytes after a 1000000-byte region + // + // CHECK31: tags: [[TAG:..]]/0e([[TAG]]) (ptr/mem) + // CHECK31-NOT: Invalid access starting at offset + // CHECK31: Cause: heap-buffer-overflow + // CHECK31: is located 1 bytes after a 30-byte region + // CHECK31: Memory tags around the buggy address + // CHECK31: [0e] + // CHECK31: Tags for short granules around the buggy address + // CHECK31: {{\[}}[[TAG]]] + // + // CHECK20-NOT: Invalid access starting at offset + // CHECK20: Cause: heap-buffer-overflow + // CHECK20: is located 10 bytes after a 20-byte region [0x{{.*}}0,0x{{.*}}4) free(x); } diff --git a/compiler-rt/test/hwasan/TestCases/stack-overflow.c b/compiler-rt/test/hwasan/TestCases/stack-overflow.c new file mode 100644 index 0000000000000000000000000000000000000000..4af506e3ecf457d4484782d44da15fa5837e1bbb --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/stack-overflow.c @@ -0,0 +1,24 @@ +// RUN: %clang_hwasan -g %s -o %t && not %run %t 2>&1 | FileCheck %s + +// Stack histories currently are not recorded on x86. +// XFAIL: target=x86_64{{.*}} + +__attribute((noinline)) void buggy() { + char c[64]; + char *volatile p = c; + p[65] = 0; +} + +int main() { + buggy(); + // CHECK: WRITE of size 1 at + // CHECK: #0 {{.*}} in buggy{{.*}}stack-overflow.c:[[@LINE-6]] + // CHECK: Cause: stack tag-mismatch + // CHECK: is located in stack of thread + // CHECK: Potentially referenced stack objects: + // CHECK: Cause: stack-buffer-overflow + // CHECK-NEXT: 0x{{.*}} is located 1 bytes after a 64-byte local variable c [0x{{.*}},0x{{.*}}) in buggy {{.*}}stack-overflow.c: + // CHECK: Memory tags around the buggy address + + // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy +} diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c index b06568e12eba7c3d548aaf81b44d68f0e1c0f129..14b9cba8aa5e4d655909bc4c4d74bcbbfa0f9018 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c @@ -21,6 +21,7 @@ char *buggy(int b) { int main() { char *p = buggy(1); // CHECK: Potentially referenced stack objects: - // CHECK-NEXT: c in buggy + // CHECK-NEXT: use-after-scope + // CHECK-NEXT: 0x{{.*}} is located 0 bytes inside a 64-byte local variable c [0x{{.*}},0x{{.*}}) in buggy p[0] = 0; } diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar.c b/compiler-rt/test/hwasan/TestCases/stack-uar.c index 48440a47d5f5f42c8baaf3c1ea632ac9ebb5814a..9fd4381a8049eb05314cafa4a3b24f1068f9536e 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar.c @@ -50,15 +50,16 @@ int main() { // CHECK: Cause: stack tag-mismatch // CHECK: is located in stack of thread // CHECK: Potentially referenced stack objects: - // CHECK-NEXT: {{zzz|yyy}} in buggy {{.*}}stack-uar.c: - // CHECK-NEXT: Memory tags around the buggy address + // CHECK: Cause: use-after-scope + // CHECK-NEXT: 0x{{.*}} is located 0 bytes inside a 2048-byte local variable {{zzz|yyy}} [0x{{.*}},0x{{.*}}) in buggy {{.*}}stack-uar.c: + // CHECK: Memory tags around the buggy address // NOSYM: Previously allocated frames: // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} - // NOSYM-NEXT: Memory tags around the buggy address + // NOSYM: Memory tags around the buggy address // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main } diff --git a/compiler-rt/test/hwasan/TestCases/stack-uas.c b/compiler-rt/test/hwasan/TestCases/stack-uas.c index 4455e5910074750ab59f5069aadaecadfee0cb72..a0e4eb02dd2269ca348fcd9748989304b67bc857 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uas.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uas.c @@ -69,15 +69,16 @@ int main() { // CHECK: Cause: stack tag-mismatch // CHECK: is located in stack of thread // CHECK: Potentially referenced stack objects: - // CHECK-NEXT: {{zzz|yyy}} in buggy {{.*}}stack-uas.c: - // CHECK-NEXT: Memory tags around the buggy address + // CHECK: Cause: use-after-scope + // CHECK-NEXT: 0x{{.*}} is located 0 bytes inside a 2048-byte local variable {{zzz|yyy}} [0x{{.*}}) in buggy {{.*}}stack-uas.c: + // CHECK: Memory tags around the buggy address // NOSYM: Previously allocated frames: // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}} - // NOSYM-NEXT: Memory tags around the buggy address + // NOSYM: Memory tags around the buggy address // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy } diff --git a/compiler-rt/test/hwasan/TestCases/stack-underflow.c b/compiler-rt/test/hwasan/TestCases/stack-underflow.c new file mode 100644 index 0000000000000000000000000000000000000000..e13955ed37b4100828cb521a803a987c2a9ef537 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/stack-underflow.c @@ -0,0 +1,24 @@ +// RUN: %clang_hwasan -g %s -o %t && not %run %t 2>&1 | FileCheck %s + +// Stack histories currently are not recorded on x86. +// XFAIL: target=x86_64{{.*}} + +__attribute((noinline)) void buggy() { + char c[64]; + char *volatile p = c; + p[-2] = 0; +} + +int main() { + buggy(); + // CHECK: WRITE of size 1 at + // CHECK: #0 {{.*}} in buggy{{.*}}stack-underflow.c:[[@LINE-6]] + // CHECK: Cause: stack tag-mismatch + // CHECK: is located in stack of thread + // CHECK: Potentially referenced stack objects: + // CHECK: Cause: stack-buffer-overflow + // CHECK-NEXT: 0x{{.*}} is located 2 bytes before a 64-byte local variable c [0x{{.*}},0x{{.*}}) in buggy {{.*}}stack-underflow.c: + // CHECK: Memory tags around the buggy address + + // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy +} diff --git a/compiler-rt/test/hwasan/TestCases/strip_path_prefix.c b/compiler-rt/test/hwasan/TestCases/strip_path_prefix.c new file mode 100644 index 0000000000000000000000000000000000000000..22705ed35ce7e9da61dbad47a9586b04a7d88292 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/strip_path_prefix.c @@ -0,0 +1,27 @@ +// RUN: %clang_hwasan -O0 -g %s -o %t && %env_hwasan_opts=strip_path_prefix=/TestCases/ not %run %t 2>&1 | FileCheck %s + +// Stack histories currently are not recorded on x86. +// XFAIL: target=x86_64{{.*}} + +#include +#include +#include + +int t; + +__attribute__((noinline)) char *buggy() { + char *volatile p; + char zzz = {}; + char yyy = {}; + p = t ? &yyy : &zzz; + return p; +} + +int main() { + char *p = buggy(); + return *p; + // CHECK: READ of size 1 at + // CHECK: #0 {{.*}} in main strip_path_prefix.c:[[@LINE-2]] + // CHECK: Potentially referenced stack objects: + // CHECK: in buggy strip_path_prefix.c:[[@LINE-12]] +} diff --git a/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp b/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87a07e311b17ed4ff2df6ef7757914ee4d411aae --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp @@ -0,0 +1,24 @@ +// RUN: %clangxx_hwasan -O0 %s -o %t && %run %t + +#include +#include +#include +#include +#include + +int main() { + auto p = std::make_unique(); + std::set ptrs; + for (unsigned i = 0;; ++i) { + void *ptr = __hwasan_tag_pointer(p.get(), i); + if (!ptrs.insert(ptr).second) + break; + fprintf(stderr, "%p, %u, %u\n", ptr, i, __hwasan_get_tag_from_pointer(ptr)); + assert(__hwasan_get_tag_from_pointer(ptr) == i); + } +#ifdef __x86_64__ + assert(ptrs.size() == 8 || ptrs.size() == 64); +#else + assert(ptrs.size() == 256); +#endif +} diff --git a/compiler-rt/test/msan/Linux/eventfd.cpp b/compiler-rt/test/msan/eventfd.cpp similarity index 75% rename from compiler-rt/test/msan/Linux/eventfd.cpp rename to compiler-rt/test/msan/eventfd.cpp index 4399211258fff1bad3b716a1efdd31f109821919..638b883fd2c1cca75d3d33b384a24a57c14ca1ef 100644 --- a/compiler-rt/test/msan/Linux/eventfd.cpp +++ b/compiler-rt/test/msan/eventfd.cpp @@ -1,4 +1,7 @@ -// RUN: %clangxx_msan -O0 %s -o %t && %run %t 2>&1 +/* RUN: %clangxx_msan -O0 %s -o %t && %run %t 2>&1 + + REQUIRES: target={{.*(linux|freebsd).*}} +*/ #include #include diff --git a/compiler-rt/test/profile/CMakeLists.txt b/compiler-rt/test/profile/CMakeLists.txt index 975e4c42f4b640f841f641c5134a2ef19f44a36d..3170d65aaf918d47643b3d1dd6f82446e7e6a342 100644 --- a/compiler-rt/test/profile/CMakeLists.txt +++ b/compiler-rt/test/profile/CMakeLists.txt @@ -6,8 +6,8 @@ set(PROFILE_TESTSUITES) set(PROFILE_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} compiler-rt-headers) list(APPEND PROFILE_TEST_DEPS profile) if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND PROFILE_TEST_DEPS llvm-profdata llvm-cov) - if(NOT APPLE AND COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) + list(APPEND PROFILE_TEST_DEPS llvm-cov llvm-lto llvm-profdata opt) + if(COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) list(APPEND PROFILE_TEST_DEPS lld) endif() endif() diff --git a/compiler-rt/test/profile/Windows/binary-id.c b/compiler-rt/test/profile/Windows/binary-id.c new file mode 100644 index 0000000000000000000000000000000000000000..dadc623b7af38ff693dded56da3f90df374ead1f --- /dev/null +++ b/compiler-rt/test/profile/Windows/binary-id.c @@ -0,0 +1,82 @@ +// REQUIRES: target={{.*windows-msvc.*}} +// REQUIRES: lld-available + +// RUN: %clang_profgen -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show --binary-ids %t.profraw > %t.out +// RUN: FileCheck %s --check-prefix=NO-BINARY-ID < %t.out +// RUN: llvm-profdata merge -o %t.profdata %t.profraw + +// RUN: %clang_profgen -fuse-ld=lld -Wl,-build-id -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show --binary-ids %t.profraw > %t.profraw.out +// RUN: FileCheck %s --check-prefix=BINARY-ID-RAW-PROF < %t.profraw.out + +// RUN: rm -rf %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: llvm-profdata show --binary-ids %t.profdir/default_*.profraw > %t.profraw.out +// RUN: FileCheck %s --check-prefix=ONE-BINARY-ID < %t.profraw.out + +// RUN: llvm-profdata merge -o %t.profdata %t.profdir/default_*.profraw +// RUN: llvm-profdata show --binary-ids %t.profdata > %t.profdata.out +// RUN: FileCheck %s --check-prefix=ONE-BINARY-ID < %t.profdata.out + +// Test raw profiles with DLLs. +// RUN: rm -rf %t.dir && split-file %s %t.dir +// RUN: %clang_profgen -O2 %t.dir/foo.c -fuse-ld=lld -Wl,-build-id -Wl,-dll -o %t.dir/foo.dll +// RUN: %clang_profgen -O2 %t.dir/bar.c -fuse-ld=lld -Wl,-build-id -Wl,-dll -o %t.dir/bar.dll +// RUN: %clang_profgen -O2 %t.dir/main.c -fuse-ld=lld -Wl,-build-id %t.dir/foo.lib %t.dir/bar.lib -o %t.dir/main.exe +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.dir/main.exe +// RUN: llvm-profdata show --binary-ids %t.profraw > %t.profraw.out +// RUN: llvm-profdata merge -o %t.profdata %t.profraw +// RUN: FileCheck %s --check-prefix=MULTI-BINARY-ID < %t.profraw.out + +// RUN: llvm-profdata merge -o %t.profdata %t.profraw +// RUN: llvm-profdata show --binary-ids %t.profdata > %t.profdata.out +// RUN: FileCheck %s --check-prefix=MULTI-BINARY-ID < %t.profraw.out + +//--- foo.c +__declspec(dllexport) void foo() {} + +//--- bar.c +__declspec(dllexport) void bar() {} + +//--- main.c +__declspec(dllimport) void foo(); +__declspec(dllimport) void bar(); +int main() { + foo(); + bar(); + return 0; +} + +// NO-BINARY-ID: Instrumentation level: Front-end +// NO-BINARY-ID-NEXT: Total functions: 3 +// NO-BINARY-ID-NEXT: Maximum function count: 1 +// NO-BINARY-ID-NEXT: Maximum internal block count: 0 +// NO-BINARY-ID-NOT: Binary IDs: + +// BINARY-ID-RAW-PROF: Instrumentation level: Front-end +// BINARY-ID-RAW-PROF-NEXT: Total functions: 3 +// BINARY-ID-RAW-PROF-NEXT: Maximum function count: 1 +// BINARY-ID-RAW-PROF-NEXT: Maximum internal block count: 0 +// BINARY-ID-RAW-PROF-NEXT: Binary IDs: +// BINARY-ID-RAW-PROF-NEXT: {{[0-9a-f]+}} + +// ONE-BINARY-ID: Instrumentation level: Front-end +// ONE-BINARY-ID-NEXT: Total functions: 3 +// ONE-BINARY-ID-NEXT: Maximum function count: 3 +// ONE-BINARY-ID-NEXT: Maximum internal block count: 0 +// ONE-BINARY-ID-NEXT: Binary IDs: +// ONE-BINARY-ID-NEXT: {{[0-9a-f]+}} + +// MULTI-BINARY-ID: Instrumentation level: Front-end +// MULTI-BINARY-ID-NEXT: Total functions: 3 +// MULTI-BINARY-ID-NEXT: Maximum function count: 1 +// MULTI-BINARY-ID-NEXT: Maximum internal block count: 0 +// MULTI-BINARY-ID-NEXT: Binary IDs: +// MULTI-BINARY-ID-NEXT: {{[0-9a-f]+}} +// MULTI-BINARY-ID-NEXT: {{[0-9a-f]+}} +// MULTI-BINARY-ID-NEXT: {{[0-9a-f]+}} diff --git a/compiler-rt/test/profile/instrprof-binary-correlate.c b/compiler-rt/test/profile/instrprof-binary-correlate.c new file mode 100644 index 0000000000000000000000000000000000000000..0e96745a9b58f4df536aef4faf13bdf529c7dd98 --- /dev/null +++ b/compiler-rt/test/profile/instrprof-binary-correlate.c @@ -0,0 +1,51 @@ +// REQUIRES: linux || windows +// Default +// RUN: %clang -o %t.normal -fprofile-instr-generate -fcoverage-mapping %S/Inputs/instrprof-debug-info-correlate-main.cpp %S/Inputs/instrprof-debug-info-correlate-foo.cpp +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal +// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw +// RUN: llvm-cov report --instr-profile=%t.normal.profdata %t.normal > %t.normal.report +// RUN: llvm-cov show --instr-profile=%t.normal.profdata %t.normal > %t.normal.show + +// With -profile-correlate=binary flag +// RUN: %clang -o %t-1.exe -fprofile-instr-generate -fcoverage-mapping -mllvm -profile-correlate=binary %S/Inputs/instrprof-debug-info-correlate-main.cpp %S/Inputs/instrprof-debug-info-correlate-foo.cpp +// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t-1.exe +// RUN: llvm-profdata merge -o %t-1.profdata --binary-file=%t-1.exe %t-1.profraw +// RUN: llvm-cov report --instr-profile=%t-1.profdata %t-1.exe > %t-1.report +// RUN: llvm-cov show --instr-profile=%t-1.profdata %t-1.exe > %t-1.show +// RUN: llvm-profdata show --all-functions --counts %t.normal.profdata > %t.normal.profdata.show +// RUN: llvm-profdata show --all-functions --counts %t-1.profdata > %t-1.profdata.show +// RUN: diff %t.normal.profdata.show %t-1.profdata.show +// RUN: diff %t.normal.report %t-1.report +// RUN: diff %t.normal.show %t-1.show + +// Strip above binary and run +// RUN: llvm-strip %t-1.exe -o %t-2.exe +// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t-2.exe +// RUN: llvm-profdata merge -o %t-2.profdata --binary-file=%t-1.exe %t-2.profraw +// RUN: llvm-cov report --instr-profile=%t-2.profdata %t-1.exe > %t-2.report +// RUN: llvm-cov show --instr-profile=%t-2.profdata %t-1.exe > %t-2.show +// RUN: llvm-profdata show --all-functions --counts %t-2.profdata > %t-2.profdata.show +// RUN: diff %t.normal.profdata.show %t-2.profdata.show +// RUN: diff %t.normal.report %t-2.report +// RUN: diff %t.normal.show %t-2.show + +// Online merging. +// RUN: env LLVM_PROFILE_FILE=%t-3.profraw %run %t.normal +// RUN: env LLVM_PROFILE_FILE=%t-4.profraw %run %t.normal +// RUN: llvm-profdata merge -o %t.normal.merged.profdata %t-3.profraw %t-4.profraw +// RUN: llvm-cov report --instr-profile=%t.normal.merged.profdata %t.normal > %t.normal.merged.report +// RUN: llvm-cov show --instr-profile=%t.normal.merged.profdata %t.normal > %t.normal.merged.show + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m-4.profraw %run %t-2.exe +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m-4.profraw %run %t-2.exe +// RUN: llvm-profdata merge -o %t-4.profdata --binary-file=%t-1.exe %t.profdir +// RUN: llvm-cov report --instr-profile=%t-4.profdata %t-1.exe > %t-4.report +// RUN: llvm-cov show --instr-profile=%t-4.profdata %t-1.exe > %t-4.show +// RUN: llvm-profdata show --all-functions --counts %t.normal.merged.profdata > %t.normal.merged.profdata.show +// RUN: llvm-profdata show --all-functions --counts %t-4.profdata > %t-4.profdata.show +// RUN: diff %t.normal.merged.profdata.show %t-4.profdata.show +// RUN: diff %t.normal.merged.report %t-4.report +// RUN: diff %t.normal.merged.show %t-4.show + +// TODO: After adding support for binary ID, test binaries with different binary IDs. diff --git a/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp b/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..860c054f69e1a64cfc6dd3d4f8955ca108a0b495 --- /dev/null +++ b/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp @@ -0,0 +1,108 @@ +// This is a regression test for ThinLTO indirect-call-promotion when candidate +// callees need to be imported from another IR module. In the C++ test case, +// `main` calls `global_func` which is defined in another module. `global_func` +// has two indirect callees, one has external linkage and one has local linkage. +// All three functions should be imported into the IR module of main. + +// What the test does: +// - Generate raw profiles from executables and convert it to indexed profiles. +// During the conversion, a profiled callee address in raw profiles will be +// converted to function hash in indexed profiles. +// - Run IRPGO profile use and ThinTLO prelink pipeline and get LLVM bitcodes +// for both cpp files in the C++ test case. +// - Generate ThinLTO summary file with LLVM bitcodes, and run `function-import` pass. +// - Run `pgo-icall-prom` pass for the IR module which needs to import callees. + +// REQUIRES: windows || linux || darwin + +// The test failed on ppc when building the instrumented binary. +// ld.lld: error: /lib/../lib64/Scrt1.o: ABI version 1 is not supported +// UNSUPPORTED: ppc + +// This test and IR test llvm/test/Transforms/PGOProfile/thinlto_indirect_call_promotion.ll +// are complementary to each other; a compiler-rt test has better test coverage +// on different platforms, and the IR test is less restrictive in terms of +// running environment and could be executed more widely. + +// Use lld as linker for more robust test. We need to REQUIRE LLVMgold.so for +// LTO if default linker is GNU ld or gold anyway. +// REQUIRES: lld-available + +// Test should fail where linkage-name and mangled-name diverges, see issue https://github.com/llvm/llvm-project/issues/74565). +// Currently, this name divergence happens on Mach-O object file format, or on +// many (but not all) 32-bit Windows systems. +// +// XFAIL: system-darwin +// +// Mark 32-bit Windows as UNSUPPORTED for now as opposed to XFAIL. This test +// should fail on many (but not all) 32-bit Windows systems and succeed on the +// rest. The flexibility in triple string parsing makes it tricky to capture +// both sets accurately. i[3-9]86 specifies arch as Triple::ArchType::x86, (win32|windows) +// specifies OS as Triple::OS::Win32 +// +// UNSUPPORTED: target={{i.86.*windows.*}} + +// RUN: rm -rf %t && split-file %s %t && cd %t + +// Do setup work for all below tests. +// Generate raw profiles from real programs and convert it into indexed profiles. +// Use clangxx_pgogen for IR level instrumentation for C++. +// RUN: %clangxx_pgogen -fuse-ld=lld -O2 lib.cpp main.cpp -o main +// RUN: env LLVM_PROFILE_FILE=main.profraw %run ./main +// RUN: llvm-profdata merge main.profraw -o main.profdata + +// Use profile on lib and get bitcode. Explicitly skip ICP pass to test ICP happens as +// expected in the IR module that imports functions from lib. +// RUN: %clang -mllvm -disable-icp -fprofile-use=main.profdata -flto=thin -O2 -c lib.cpp -o lib.bc + +// Use profile on main and get bitcode. +// RUN: %clang -fprofile-use=main.profdata -flto=thin -O2 -c main.cpp -o main.bc + +// Run llvm-lto to get summary file. +// RUN: llvm-lto -thinlto -o summary main.bc lib.bc + +// Test the imports of functions. Default import thresholds would work but do +// explicit override to be more futureproof. Note all functions have one basic +// block with a function-entry-count of one, so they are actually hot functions +// per default profile summary hotness cutoff. +// RUN: opt -passes=function-import -import-instr-limit=100 -import-cold-multiplier=1 -summary-file summary.thinlto.bc main.bc -o main.import.bc -print-imports 2>&1 | FileCheck %s --check-prefix=IMPORTS + +// Test that both candidates are ICP'ed and there is no `!VP` in the IR. +// RUN: opt main.import.bc -icp-lto -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom 2>&1 | FileCheck %s --check-prefixes=ICP-IR,ICP-REMARK --implicit-check-not="!VP" + +// IMPORTS-DAG: main.cpp: Import {{.*}}callee1{{.*}} +// IMPORTS-DAG: main.cpp: Import {{.*}}callee0{{.*}}llvm.[[#]] +// IMPORTS-DAG: main.cpp: Import {{.*}}global_func{{.*}} + +// PGOName-DAG: define {{.*}}callee1{{.*}} !prof ![[#]] { +// PGOName-DAG: define internal {{.*}}callee0{{.*}} !prof ![[#]] !PGOFuncName ![[#MD:]] { +// PGOName-DAG: ![[#MD]] = !{!"{{.*}}lib.cpp;{{.*}}callee0{{.*}}"} + +// ICP-REMARK: Promote indirect call to {{.*}}callee0{{.*}}llvm.[[#]] with count 1 out of 1 +// ICP-REMARK: Promote indirect call to {{.*}}callee1{{.*}} with count 1 out of 1 + +// ICP-IR: br i1 %[[#]], label %if.true.direct_targ, label %if.false.orig_indirect, !prof ![[#BRANCH_WEIGHT1:]] +// ICP-IR: br i1 %[[#]], label %if.true.direct_targ1, label %if.false.orig_indirect2, !prof ![[#BRANCH_WEIGHT1]] +// ICP-IR: ![[#BRANCH_WEIGHT1]] = !{!"branch_weights", i32 1, i32 0} + +//--- lib.h +void global_func(); + +//--- lib.cpp +#include "lib.h" +static void callee0() {} +void callee1() {} +typedef void (*FPT)(); +FPT calleeAddrs[] = {callee0, callee1}; +// `global_func`` might call one of two indirect callees. callee0 has internal +// linkage and callee1 has external linkage. +void global_func() { + FPT fp = calleeAddrs[0]; + fp(); + fp = calleeAddrs[1]; + fp(); +} + +//--- main.cpp +#include "lib.h" +int main() { global_func(); } diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c new file mode 100644 index 0000000000000000000000000000000000000000..13240234a1c79bf48c5cd5d13658bdafdd468c50 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c @@ -0,0 +1,112 @@ +// RUN: %clang -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t + +// The test uses pthread barriers which are not available on Darwin. +// UNSUPPORTED: darwin + +// FIXME: It probably hangs on this platform. +// UNSUPPORTED: ppc + +// FIXME: TSAN does not lock allocator. +// UNSUPPORTED: tsan + +// FIXME: False stack overflow report +// UNSUPPORTED: android && asan + +// FIXME: Requires `FutexWait` implementation. See __asan::InstallAtForkHandler. +// UNSUPPORTED: target={{.*solaris.*}} +// UNSUPPORTED: target={{.*netbsd.*}} +// UNSUPPORTED: target={{.*apple.*}} + +// Forking in multithread environment is unsupported. However we already have +// some workarounds, and will add more, so this is the test. +// The test try to check two things: +// 1. Internal mutexes used by `inparent` thread do not deadlock `inchild` +// thread. +// 2. Stack poisoned by `inparent` is not poisoned in `inchild` thread. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sanitizer_common/sanitizer_specific.h" + +static const size_t kBufferSize = 8192; + +pthread_barrier_t bar; + +// Without appropriate workarounds this code can cause the forked process to +// start with locked internal mutexes. +void ShouldNotDeadlock() { + // Don't bother with leaks, we try to trigger allocator or lsan deadlock. + __lsan_disable(); + void *volatile p = malloc(10); + __lsan_do_recoverable_leak_check(); + // Allocator still in broken state, `free` may report errors. + // free(p); + __lsan_enable(); +} + +// Prevent stack buffer cleanup by instrumentation. +#define NOSAN __attribute__((no_sanitize("address", "hwaddress", "memory"))) + +NOSAN static void *inparent(void *arg) { + char t[kBufferSize]; + make_mem_bad(t, sizeof(t)); + + pthread_barrier_wait(&bar); + + for (;;) + ShouldNotDeadlock(); + + return 0; +} + +NOSAN static void *inchild(void *arg) { + char t[kBufferSize]; + check_mem_is_good(t, sizeof(t)); + ShouldNotDeadlock(); + return 0; +} + +int main(void) { +#if __has_feature(hwaddress_sanitizer) + __hwasan_enable_allocator_tagging(); +#endif + + pid_t pid; + + pthread_barrier_init(&bar, NULL, 2); + pthread_t thread_id; + while (pthread_create(&thread_id, 0, &inparent, 0) != 0) { + } + pthread_barrier_wait(&bar); + + pid = fork(); + switch (pid) { + case -1: + perror("fork"); + return -1; + case 0: + ShouldNotDeadlock(); + while (pthread_create(&thread_id, 0, &inchild, 0) != 0) { + } + pthread_join(thread_id, NULL); + _exit(0); + break; + default: { + int status; + pid_t child = waitpid(pid, &status, /*options=*/0); + assert(pid == child); + assert(WIFEXITED(status)); + assert(WEXITSTATUS(status) == 0); + break; + } + } + + return 0; +} diff --git a/compiler-rt/test/sanitizer_common/sanitizer_specific.h b/compiler-rt/test/sanitizer_common/sanitizer_specific.h index 1a802020cfd66836d7dec9aebd46f9c46ba9885f..99a4dd98c614a1eaed0c979606f5e8d3f69f08f0 100644 --- a/compiler-rt/test/sanitizer_common/sanitizer_specific.h +++ b/compiler-rt/test/sanitizer_common/sanitizer_specific.h @@ -1,6 +1,12 @@ #ifndef __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__ #define __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__ +#include + +__attribute__((weak)) int __lsan_do_recoverable_leak_check() { return 0; } +__attribute__((weak)) void __lsan_disable(void) {} +__attribute__((weak)) void __lsan_enable(void) {} + #ifndef __has_feature # define __has_feature(x) 0 #endif @@ -10,6 +16,8 @@ static void check_mem_is_good(void *p, size_t s) { __msan_check_mem_is_initialized(p, s); } +static void make_mem_good(void *p, size_t s) { __msan_unpoison(p, s); } +static void make_mem_bad(void *p, size_t s) { __msan_poison(p, s); } #elif __has_feature(address_sanitizer) # include # include @@ -17,8 +25,40 @@ static void check_mem_is_good(void *p, size_t s) { if (__asan_region_is_poisoned(p, s)) abort(); } +static void make_mem_good(void *p, size_t s) { + __asan_unpoison_memory_region(p, s); +} +static void make_mem_bad(void *p, size_t s) { + __asan_poison_memory_region(p, s); +} +#elif __has_feature(hwaddress_sanitizer) +# include +# include +static void check_mem_is_good(void *p, size_t s) { + if (__hwasan_test_shadow(p, s) != -1) + abort(); +} +static void make_mem_good(void *p, size_t s) { + __hwasan_tag_memory(p, __hwasan_get_tag_from_pointer(p), s); +} +static void make_mem_bad(void *p, size_t s) { + uint8_t tag = ~__hwasan_get_tag_from_pointer(p); + if (!tag) { + // Nothing wrong with tag zero, but non-zero tags help to detect never + // tagged memory. + tag = 1; + } + __hwasan_tag_memory(p, tag, s); + // With misaligned `p` or short granules we can't guarantee tag mismatch. + if (__hwasan_test_shadow(p, s) != 0) + abort(); + if (s > 1 && __hwasan_test_shadow(((char *)p) + s - 1, 1) != 0) + abort(); +} #else static void check_mem_is_good(void *p, size_t s) {} +static void make_mem_good(void *p, size_t s) {} +static void make_mem_bad(void *p, size_t s) {} #endif -#endif // __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__ \ No newline at end of file +#endif // __SANITIZER_COMMON_SANITIZER_SPECIFIC_H__ diff --git a/compiler-rt/test/tsan/pthread_mutex_clocklock.cpp b/compiler-rt/test/tsan/pthread_mutex_clocklock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63d329928080de3aa310d92fbfc928c2f584bc74 --- /dev/null +++ b/compiler-rt/test/tsan/pthread_mutex_clocklock.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s +// REQUIRES: glibc-2.30 +#include +#include + +pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; +struct timespec ts = {0}; + +void *tfunc(void *p) { + if (!pthread_mutex_trylock(&m)) { + puts("Second thread could not lock mutex"); + pthread_mutex_unlock(&m); + } + return p; +} + +int main() { + if (!pthread_mutex_clocklock(&m, CLOCK_REALTIME, &ts)) { + pthread_t thr; + pthread_create(&thr, 0, tfunc, 0); + pthread_join(thr, 0); + pthread_mutex_unlock(&m); + } else + puts("Failed to lock mutex"); + fprintf(stderr, "PASS\n"); +} + +// CHECK-NOT: WARNING: ThreadSanitizer: unlock of an unlocked mutex +// CHECK: PASS diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index 03d4310466485c578c2e04c75acf781be9bbef43..16eb67f2e27c8120b9cf53d2a89f82d9e1692b1c 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -315,6 +315,9 @@ end * When a file included via an `INCLUDE` line or `#include` directive has a continuation marker at the end of its last line in free form, Fortran line continuation works. +* A `NAMELIST` input group may omit its trailing `/` character if + it is followed by another `NAMELIST` input group. +* A `NAMELIST` input group may begin with either `&` or `$`. ### Extensions supported when enabled by options @@ -641,6 +644,16 @@ module m end ``` +* When an intrinsic procedure appears in the specification part of a module + only in function references, but not an explicit `INTRINSIC` statement, + its name is not brought into other scopes by a `USE` statement. + +* Should hexadecimal floating-point input editing apply any rounding? + F'2023 subclause 13.7.2.3.8 only discusses rounding in the context of + decimal-to-binary conversion; it would seem to not apply, and so + we don't round. This seems to be how the Intel Fortran compilers + behave. + ## De Facto Standard Features * `EXTENDS_TYPE_OF()` returns `.TRUE.` if both of its arguments have the @@ -650,3 +663,7 @@ end but every Fortran compiler allows the encoding to be changed on an open unit. +* A `NAMELIST` input item that references a scalar element of a vector + or contiguous array can be used as the initial element of a storage + sequence. For example, "&GRP A(1)=1. 2. 3./" is treated as if had been + "&GRP A(1:)=1. 2. 3./". diff --git a/flang/docs/FlangDriver.md b/flang/docs/FlangDriver.md index 5231e78335f6add75cc13369921adc1fd217b39e..fa39889927e0ebf0f06c7e9c4d613ac2fb486966 100644 --- a/flang/docs/FlangDriver.md +++ b/flang/docs/FlangDriver.md @@ -163,6 +163,63 @@ forward compiler options to the frontend driver, `flang-new -fc1`. You can read more on the design of `clangDriver` in Clang's [Driver Design & Internals](https://clang.llvm.org/docs/DriverInternals.html). +## Linker Driver +When used as a linker, Flang's frontend driver assembles the command line for an +external linker command (e.g., LLVM's `lld`) and invokes it to create the final +executable by linking static and shared libraries together with all the +translation units supplied as object files. + +By default, the Flang linker driver adds several libraries to the linker +invocation to make sure that all entrypoints for program start +(Fortran's program unit) and runtime routines can be resolved by the linker. + +An abridged example (only showing the Fortran specific linker flags, omission +indicated by `[...]`) for such a linker invocation on a Linux system would look +like this: + +``` +$ flang -v -o example example.o +"/usr/bin/ld" [...] example.o [...] "--whole-archive" "-lFortran_main" +"--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal" [...] +``` + +The automatically added libraries are: + +* `Fortran_main`: Provides the main entry point `main` that then invokes + `_QQmain` with the Fortran program unit. This library has a dependency to + the `FortranRuntime` library. +* `FortranRuntime`: Provides most of the Flang runtime library. +* `FortranDecimal`: Provides operations for decimal numbers. + +The default is that, when using Flang as the linker, one of the Fortran +translation units provides the program unit and therefore it is assumed that +Fortran is the main code part (calling into C/C++ routines via `BIND (C)` +interfaces). When composing the linker commandline, Flang uses +`--whole-archive` and `--no-whole-archive` (Windows: `/WHOLEARCHIVE:`, +Darwin & AIX: *not implemented yet*) to make sure that all for `Fortran_main` +is processed by the linker. This is done to issue a proper error message when +multiple definitions of `main` occur. This happens, for instance, when linking +a code that has a Fortran program unit with a C/C++ code that also defines a +`main` function. A user may be required to explicitly provide the C++ runtime +libraries at link time (e.g., via `-lstdc++` for STL) + +If the code is C/C++ based and invokes Fortran routines, one can either use Clang +or Flang as the linker driver. If Clang is used, it will automatically all +required runtime libraries needed by C++ (e.g., for STL) to the linker invocation. +In this case, one has to explicitly provide the Fortran runtime libraries +`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link +and use the `-fno-fortran-main` flag. This flag removes +`Fortran_main` from the linker stage and hence requires one of the C/C++ +translation units to provide a definition of the `main` function. In this case, +it may be required to explicitly supply C++ runtime libraries as mentioned above. + +When creating shared or static libraries using Flang with `-shared` or `-static` +flag, Fortran_main is automatically removed from the linker stage (i.e., +`-fno-fortran-main` is on by default). It is assumed that when creating a +static or shared library, the generated library does not need a `main` +function, as a final link stage will occur that will provide the `Fortran_main` +library when creating the final executable. + ## Frontend Driver Flang's frontend driver is the main interface between compiler developers and the Flang frontend. The high-level design is similar to Clang's frontend diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md index fef2b4ea4dd8c8527dd6f436dee503e60bdf13df..189920a0881b27ab904dd921dd391e02c31196b7 100644 --- a/flang/docs/Intrinsics.md +++ b/flang/docs/Intrinsics.md @@ -695,6 +695,11 @@ CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, LOC MALLOC ``` +### Library subroutine +``` +CALL GETLOG(USRNAME) +``` + ## Intrinsic Procedure Name Resolution When the name of a procedure in a program is the same as the one of an intrinsic @@ -754,6 +759,7 @@ This phase currently supports all the intrinsic procedures listed above but the | Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK | | Atomic intrinsic subroutines | ATOMIC_ADD | | Collective intrinsic subroutines | CO_REDUCE | +| Library subroutines | GETLOG| ### Intrinsic Function Folding diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 6f10553cdcb4c0d22f0f9b8c75b3d8ce320ad4e2..2338fa1b14a37b60b27e41ad94490f4339f9aa20 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -281,7 +281,7 @@ public: READ_FEATURE(ErrorRecovery) READ_FEATURE(EventPostStmt) READ_FEATURE(EventWaitStmt) - READ_FEATURE(EventWaitStmt::EventWaitSpec) + READ_FEATURE(EventWaitSpec) READ_FEATURE(ExecutableConstruct) READ_FEATURE(ExecutionPart) READ_FEATURE(ExecutionPartConstruct) @@ -438,6 +438,7 @@ public: READ_FEATURE(NamelistStmt::Group) READ_FEATURE(NonLabelDoStmt) READ_FEATURE(NoPass) + READ_FEATURE(NotifyWaitStmt) READ_FEATURE(NullifyStmt) READ_FEATURE(NullInit) READ_FEATURE(ObjectDecl) diff --git a/flang/include/flang/Common/uint128.h b/flang/include/flang/Common/uint128.h index bfd2eef01f6f08a3324ef41cf28529d48b732d4a..03e44eb6997d5bdbaf9193c4790e413b6dcee81a 100644 --- a/flang/include/flang/Common/uint128.h +++ b/flang/include/flang/Common/uint128.h @@ -33,15 +33,18 @@ public: constexpr Int128(unsigned n) : low_{n} {} constexpr Int128(unsigned long n) : low_{n} {} constexpr Int128(unsigned long long n) : low_{n} {} - constexpr Int128(int n) - : low_{static_cast(n)}, high_{-static_cast( - n < 0)} {} - constexpr Int128(long n) - : low_{static_cast(n)}, high_{-static_cast( - n < 0)} {} - constexpr Int128(long long n) - : low_{static_cast(n)}, high_{-static_cast( - n < 0)} {} + constexpr Int128(int n) { + low_ = static_cast(n); + high_ = -static_cast(n < 0); + } + constexpr Int128(long n) { + low_ = static_cast(n); + high_ = -static_cast(n < 0); + } + constexpr Int128(long long n) { + low_ = static_cast(n); + high_ = -static_cast(n < 0); + } constexpr Int128(const Int128 &) = default; constexpr Int128(Int128 &&) = default; constexpr Int128 &operator=(const Int128 &) = default; @@ -246,7 +249,10 @@ public: } private: - constexpr Int128(std::uint64_t hi, std::uint64_t lo) : low_{lo}, high_{hi} {} + constexpr Int128(std::uint64_t hi, std::uint64_t lo) { + low_ = lo; + high_ = hi; + } constexpr int LeadingZeroes() const { if (high_ == 0) { return 64 + LeadingZeroBitCount(low_); @@ -255,7 +261,13 @@ private: } } static constexpr std::uint64_t topBit{std::uint64_t{1} << 63}; +#if FLANG_LITTLE_ENDIAN std::uint64_t low_{0}, high_{0}; +#elif FLANG_BIG_ENDIAN + std::uint64_t high_{0}, low_{0}; +#else +#error host endianness is not known +#endif }; using UnsignedInt128 = Int128; diff --git a/flang/include/flang/Decimal/binary-floating-point.h b/flang/include/flang/Decimal/binary-floating-point.h index b9346a8585e2d2463509861605d3bcc009865ba3..d1992819f85aa610b9aa671bed1f905ca1f441fb 100644 --- a/flang/include/flang/Decimal/binary-floating-point.h +++ b/flang/include/flang/Decimal/binary-floating-point.h @@ -143,7 +143,7 @@ public: if (IsNaN() || IsInfinite() || keepBits >= binaryPrecision) { return true; } - int lostBits{binaryPrecision - keepBits}; + int lostBits{keepBits < binaryPrecision ? binaryPrecision - keepBits : 0}; RawType lostMask{static_cast((RawType{1} << lostBits) - 1)}; if (RawType lost{static_cast(raw_ & lostMask)}; lost != 0) { bool increase{false}; diff --git a/flang/include/flang/Decimal/decimal.h b/flang/include/flang/Decimal/decimal.h index a4e0ee7c8474607b08859c15273abd3b159b574d..f0997fb63df0185cfeaccc9bf83a76688f997d8d 100644 --- a/flang/include/flang/Decimal/decimal.h +++ b/flang/include/flang/Decimal/decimal.h @@ -34,6 +34,7 @@ enum ConversionResultFlags { Overflow = 1, Inexact = 2, Invalid = 4, + Underflow = 8, }; struct ConversionToDecimalResult { diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index 8a47a9f651661ad5f3a91aaa66f7f05f26e31f38..c0cbb05c009d6b146ce54807934d70b2e5c8fb35 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -1227,10 +1227,12 @@ bool IsFunctionResult(const Symbol &); bool IsKindTypeParameter(const Symbol &); bool IsLenTypeParameter(const Symbol &); bool IsExtensibleType(const DerivedTypeSpec *); +bool IsSequenceOrBindCType(const DerivedTypeSpec *); bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name); bool IsBuiltinCPtr(const Symbol &); bool IsEventType(const DerivedTypeSpec *); bool IsLockType(const DerivedTypeSpec *); +bool IsNotifyType(const DerivedTypeSpec *); // Is this derived type TEAM_TYPE from module ISO_FORTRAN_ENV? bool IsTeamType(const DerivedTypeSpec *); // Is this derived type TEAM_TYPE, C_PTR, or C_FUNPTR? diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index 72e7bdab12a14da640c72264867685115e5d65fb..9d03ec88a56b8a895687a7e305e3fafd63e457cf 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -38,6 +38,7 @@ CODEGENOPT(Underscoring, 1, 1) ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use. ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use +ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) ///< Enable the usage of frame pointers #undef CODEGENOPT #undef ENUM_CODEGENOPT diff --git a/flang/include/flang/ISO_Fortran_binding.h b/flang/include/flang/ISO_Fortran_binding.h index dd384c516263e5ffa686e0eeaee6af9ee72158d3..4a28d3322a38f0cddb9c08d248178eb27ec59cc6 100644 --- a/flang/include/flang/ISO_Fortran_binding.h +++ b/flang/include/flang/ISO_Fortran_binding.h @@ -189,8 +189,8 @@ RT_API_ATTRS void *CFI_address( RT_API_ATTRS int CFI_allocate(CFI_cdesc_t *, const CFI_index_t lower_bounds[], const CFI_index_t upper_bounds[], size_t elem_len); RT_API_ATTRS int CFI_deallocate(CFI_cdesc_t *); -int CFI_establish(CFI_cdesc_t *, void *base_addr, CFI_attribute_t, CFI_type_t, - size_t elem_len, CFI_rank_t, const CFI_index_t extents[]); +RT_API_ATTRS int CFI_establish(CFI_cdesc_t *, void *base_addr, CFI_attribute_t, + CFI_type_t, size_t elem_len, CFI_rank_t, const CFI_index_t extents[]); RT_API_ATTRS int CFI_is_contiguous(const CFI_cdesc_t *); RT_API_ATTRS int CFI_section(CFI_cdesc_t *, const CFI_cdesc_t *source, const CFI_index_t lower_bounds[], const CFI_index_t upper_bounds[], diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index 980fde881373249d9127c8e965e329ccea964194..c19dcbdcdb39022f908ef090ed289fc99be7e80a 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -58,6 +58,8 @@ struct Variable; using SomeExpr = Fortran::evaluate::Expr; using SymbolRef = Fortran::common::Reference; +using TypeConstructionStack = + llvm::SmallVector>; class StatementContext; using ExprToValueMap = llvm::DenseMap; @@ -231,6 +233,10 @@ public: const Fortran::semantics::DerivedTypeSpec &typeSpec, fir::RecordType type) = 0; + /// Get stack of derived type in construction. This is an internal entry point + /// for the type conversion utility to allow lowering recursive derived types. + virtual TypeConstructionStack &getTypeConstructionStack() = 0; + //===--------------------------------------------------------------------===// // Locations //===--------------------------------------------------------------------===// @@ -280,6 +286,10 @@ public: // Miscellaneous //===--------------------------------------------------------------------===// + /// Generate IR for Evaluation \p eval. + virtual void genEval(pft::Evaluation &eval, + bool unstructuredContext = true) = 0; + /// Return options controlling lowering behavior. const Fortran::lower::LoweringOptions &getLoweringOptions() const { return loweringOptions; diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h index c7dca4f8f1348e0e8d195d350b95327203c01491..e77ac4e179ba861a8a2a63902871e9b29bc0b7b7 100644 --- a/flang/include/flang/Lower/CallInterface.h +++ b/flang/include/flang/Lower/CallInterface.h @@ -303,6 +303,11 @@ public: /// index. std::optional getPassArgIndex() const; + /// Get the passed-object if any. Crashes if there is a passed object + /// but it was not placed in the inputs yet. Return a null value + /// otherwise. + mlir::Value getIfPassedArg() const; + /// Return the procedure symbol if this is a call to a user defined /// procedure. const Fortran::semantics::Symbol *getProcedureSymbol() const; @@ -314,8 +319,8 @@ public: mlir::Value addr, mlir::Value len); /// If this is a call to a procedure pointer or dummy, returns the related - /// symbol. Nullptr otherwise. - const Fortran::semantics::Symbol *getIfIndirectCallSymbol() const; + /// procedure designator. Nullptr otherwise. + const Fortran::evaluate::ProcedureDesignator *getIfIndirectCall() const; /// Get the input vector once it is complete. llvm::ArrayRef getInputs() const { diff --git a/flang/include/flang/Lower/ConvertProcedureDesignator.h b/flang/include/flang/Lower/ConvertProcedureDesignator.h index ae772c52e425bc104c569423a1678e6c5f330b54..b3e0dc3fa53acc3d5a674d3f46d56683eb9f3707 100644 --- a/flang/include/flang/Lower/ConvertProcedureDesignator.h +++ b/flang/include/flang/Lower/ConvertProcedureDesignator.h @@ -60,5 +60,13 @@ mlir::Value convertProcedureDesignatorInitialTarget(Fortran::lower::AbstractConverter &, mlir::Location, const Fortran::semantics::Symbol &sym); + +/// Given the value of a "PASS" actual argument \p passedArg and the +/// evaluate::ProcedureDesignator for the call, address and dereference +/// the argument's procedure pointer component that must be called. +mlir::Value derefPassProcPointerComponent( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + const Fortran::evaluate::ProcedureDesignator &proc, mlir::Value passedArg, + Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx); } // namespace Fortran::lower #endif // FORTRAN_LOWER_CONVERT_PROCEDURE_DESIGNATOR_H diff --git a/flang/include/flang/Lower/OpenMP.h b/flang/include/flang/Lower/OpenMP.h index c9162761a08d54a71d4cbad47856477d882749e0..6e772c43d8c46e7c5efa8c150e04827ec7a29fb8 100644 --- a/flang/include/flang/Lower/OpenMP.h +++ b/flang/include/flang/Lower/OpenMP.h @@ -42,6 +42,7 @@ class SemanticsContext; namespace lower { class AbstractConverter; +class SymMap; namespace pft { struct Evaluation; @@ -52,10 +53,18 @@ struct Variable; void genOpenMPTerminator(fir::FirOpBuilder &, mlir::Operation *, mlir::Location); -void genOpenMPConstruct(AbstractConverter &, semantics::SemanticsContext &, - pft::Evaluation &, const parser::OpenMPConstruct &); +void genOpenMPConstruct(AbstractConverter &, Fortran::lower::SymMap &, + semantics::SemanticsContext &, pft::Evaluation &, + const parser::OpenMPConstruct &); void genOpenMPDeclarativeConstruct(AbstractConverter &, pft::Evaluation &, const parser::OpenMPDeclarativeConstruct &); +/// Symbols in OpenMP code can have flags (e.g. threadprivate directive) +/// that require additional handling when lowering the corresponding +/// variable. Perform such handling according to the flags on the symbol. +/// The variable \p var is required to have a `Symbol`. +void genOpenMPSymbolProperties(AbstractConverter &converter, + const pft::Variable &var); + int64_t getCollapseValue(const Fortran::parser::OmpClauseList &clauseList); void genThreadprivateOp(AbstractConverter &, const pft::Variable &); void genDeclareTargetIntGlobal(AbstractConverter &, const pft::Variable &); diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h index 9c6696ff79dae16c65fa1d7b8ccd72094e163b0d..8d32c32352916ce3b0f387a9f0212240abef63cd 100644 --- a/flang/include/flang/Lower/PFTBuilder.h +++ b/flang/include/flang/Lower/PFTBuilder.h @@ -100,13 +100,14 @@ using ActionStmts = std::tuple< parser::EventPostStmt, parser::EventWaitStmt, parser::ExitStmt, parser::FailImageStmt, parser::FlushStmt, parser::FormTeamStmt, parser::GotoStmt, parser::IfStmt, parser::InquireStmt, parser::LockStmt, - parser::NullifyStmt, parser::OpenStmt, parser::PointerAssignmentStmt, - parser::PrintStmt, parser::ReadStmt, parser::ReturnStmt, parser::RewindStmt, - parser::StopStmt, parser::SyncAllStmt, parser::SyncImagesStmt, - parser::SyncMemoryStmt, parser::SyncTeamStmt, parser::UnlockStmt, - parser::WaitStmt, parser::WhereStmt, parser::WriteStmt, - parser::ComputedGotoStmt, parser::ForallStmt, parser::ArithmeticIfStmt, - parser::AssignStmt, parser::AssignedGotoStmt, parser::PauseStmt>; + parser::NotifyWaitStmt, parser::NullifyStmt, parser::OpenStmt, + parser::PointerAssignmentStmt, parser::PrintStmt, parser::ReadStmt, + parser::ReturnStmt, parser::RewindStmt, parser::StopStmt, + parser::SyncAllStmt, parser::SyncImagesStmt, parser::SyncMemoryStmt, + parser::SyncTeamStmt, parser::UnlockStmt, parser::WaitStmt, + parser::WhereStmt, parser::WriteStmt, parser::ComputedGotoStmt, + parser::ForallStmt, parser::ArithmeticIfStmt, parser::AssignStmt, + parser::AssignedGotoStmt, parser::PauseStmt>; using OtherStmts = std::tuple; diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h index e71496edad9ba7f6a3d91b55384147438c7c7d81..77e98a1e019e79f38ad6fd15a08c09a8302ef324 100644 --- a/flang/include/flang/Lower/Runtime.h +++ b/flang/include/flang/Lower/Runtime.h @@ -34,6 +34,7 @@ namespace parser { struct EventPostStmt; struct EventWaitStmt; struct LockStmt; +struct NotifyWaitStmt; struct PauseStmt; struct StopStmt; struct SyncAllStmt; @@ -49,6 +50,8 @@ class AbstractConverter; // Lowering of Fortran statement related runtime (other than IO and maths) +void genNotifyWaitStatement(AbstractConverter &, + const parser::NotifyWaitStmt &); void genEventPostStatement(AbstractConverter &, const parser::EventPostStmt &); void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &); void genLockStatement(AbstractConverter &, const parser::LockStmt &); diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h index e7561dffb7563519dbdc984308c15aa2a8f6809c..46dc79f41a18b4bd5cd2da3585fc56dbbbe794bc 100644 --- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h +++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h @@ -59,7 +59,7 @@ public: bool isVariable() const { return !isValue(); } bool isMutableBox() const { return hlfir::isBoxAddressType(getType()); } bool isProcedurePointer() const { - return hlfir::isBoxProcAddressType(getType()); + return fir::isBoxProcAddressType(getType()); } bool isBoxAddressOrValue() const { return hlfir::isBoxAddressOrValueType(getType()); @@ -404,15 +404,15 @@ mlir::Value inlineElementalOp( std::pair> convertToValue(mlir::Location loc, fir::FirOpBuilder &builder, - const hlfir::Entity &entity); + hlfir::Entity entity); std::pair> convertToAddress(mlir::Location loc, fir::FirOpBuilder &builder, - const hlfir::Entity &entity, mlir::Type targetType); + hlfir::Entity entity, mlir::Type targetType); std::pair> convertToBox(mlir::Location loc, fir::FirOpBuilder &builder, - const hlfir::Entity &entity, mlir::Type targetType); + hlfir::Entity entity, mlir::Type targetType); /// Clone an hlfir.elemental_addr into an hlfir.elemental value. hlfir::ElementalOp cloneToElementalOp(mlir::Location loc, diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index ba0c4806c759e152aa2d9fe1242c821bee1df6cf..dba946975e19285b4ba386830de07033c1f514e8 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -202,6 +202,7 @@ struct IntrinsicLibrary { fir::ExtendedValue genCAssociatedCPtr(mlir::Type, llvm::ArrayRef); void genCFPointer(llvm::ArrayRef); + void genCFProcPointer(llvm::ArrayRef); fir::ExtendedValue genCFunLoc(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genCLoc(mlir::Type, llvm::ArrayRef); void genDateAndTime(llvm::ArrayRef); diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td index 5e47119582776aa796afdebd4d3a49d670211a09..0d20a669a15a1f7f03607bb8136875fc03a58001 100644 --- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td +++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td @@ -63,7 +63,10 @@ def TargetRewritePass : Pass<"target-rewrite", "mlir::ModuleOp"> { "Disable target-specific conversion of CHARACTER.">, Option<"noComplexConversion", "no-complex-conversion", "bool", /*default=*/"false", - "Disable target-specific conversion of COMPLEX."> + "Disable target-specific conversion of COMPLEX.">, + Option<"noStructConversion", "no-struct-conversion", + "bool", /*default=*/"false", + "Disable target-specific conversion of derived type value."> ]; } diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h index 7d8e548d89a18b5ab1624997d95f0a539306bb71..5ea96c900bc63048c0d00999ab1670c014bd103a 100644 --- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h +++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h @@ -34,6 +34,7 @@ std::unique_ptr createFirCodeGenRewritePass(); struct TargetRewriteOptions { bool noCharacterConversion{}; bool noComplexConversion{}; + bool noStructConversion{}; }; /// Prerequiste pass for code gen. Perform intermediate rewrites to tailor the diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h index 2abcc6547bbabf6343272695b7bd257f9fa38742..ecfa9839617dab037bdfba748d5e5485ff22e8e4 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -118,8 +118,8 @@ inline bool isa_derived(mlir::Type t) { return t.isa(); } /// Is `t` type(c_ptr) or type(c_funptr)? inline bool isa_builtin_cptr_type(mlir::Type t) { if (auto recTy = t.dyn_cast_or_null()) - return recTy.getName().endswith("T__builtin_c_ptr") || - recTy.getName().endswith("T__builtin_c_funptr"); + return recTy.getName().ends_with("T__builtin_c_ptr") || + recTy.getName().ends_with("T__builtin_c_funptr"); return false; } @@ -436,6 +436,12 @@ inline bool isBoxAddressOrValue(mlir::Type t) { return fir::unwrapRefType(t).isa(); } +/// Is this a fir.boxproc address type? +inline bool isBoxProcAddressType(mlir::Type t) { + t = fir::dyn_cast_ptrEleTy(t); + return t && t.isa(); +} + /// Return a string representation of `ty`. /// /// fir.array<10x10xf32> -> prefix_10x10xf32 diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h index e8f28485298277d643aca1c04bdcdd66854bd10c..aa68d0811c4868adb6517459a6ebfe534d55f339 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h +++ b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h @@ -67,12 +67,6 @@ inline bool isBoxAddressType(mlir::Type type) { return type && type.isa(); } -/// Is this a fir.boxproc address type? -inline bool isBoxProcAddressType(mlir::Type type) { - type = fir::dyn_cast_ptrEleTy(type); - return type && type.isa(); -} - /// Is this a fir.box or fir.class address or value type? inline bool isBoxAddressOrValueType(mlir::Type type) { return fir::unwrapRefType(type).isa(); diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td index 1f5bc42c43e65c4edc554eea8643ca56b11a1247..254771ca1780cf04a7e094f5548418b7de91f77f 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td @@ -383,7 +383,7 @@ def hlfir_AnyOp : hlfir_Op<"any", [DeclareOpInterfaceMethods]> { +def hlfir_CountOp : hlfir_Op<"count", [DeclareOpInterfaceMethods]> { let summary = "COUNT transformational intrinsic"; let description = [{ Takes a logical and counts the number of true values. @@ -391,14 +391,13 @@ def hlfir_CountOp : hlfir_Op<"count", [AttrSizedOperandSegments, DeclareOpInterf let arguments = (ins AnyFortranLogicalArrayObject:$mask, - Optional:$dim, - Optional:$kind + Optional:$dim ); let results = (outs AnyFortranValue); let assemblyFormat = [{ - $mask (`dim` $dim^)? (`kind` $kind^)? attr-dict `:` functional-type(operands, results) + $mask (`dim` $dim^)? attr-dict `:` functional-type(operands, results) }]; let hasVerifier = 1; @@ -484,6 +483,32 @@ def hlfir_MinlocOp : hlfir_Op<"minloc", [AttrSizedOperandSegments, let hasVerifier = 1; } +def hlfir_MaxlocOp : hlfir_Op<"maxloc", [AttrSizedOperandSegments, + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods]> { + let summary = "MAXLOC transformational intrinsic"; + let description = [{ + Maxlocs of an array. + }]; + + let arguments = (ins + AnyFortranArrayObject:$array, + Optional:$dim, + Optional:$mask, + Optional>:$back, + DefaultValuedAttr:$fastmath + ); + + let results = (outs AnyFortranValue); + + let assemblyFormat = [{ + $array (`dim` $dim^)? (`mask` $mask^)? (`back` $back^)? attr-dict `:` functional-type(operands, results) + }]; + + let hasVerifier = 1; +} + def hlfir_ProductOp : hlfir_Op<"product", [AttrSizedOperandSegments, DeclareOpInterfaceMethods, DeclareOpInterfaceMethods]> { diff --git a/flang/include/flang/Optimizer/Support/InternalNames.h b/flang/include/flang/Optimizer/Support/InternalNames.h index f3f9fe70518935905d3a8d74c95f9710060511db..23a03854c4abd007894331a05494a385594f75ef 100644 --- a/flang/include/flang/Optimizer/Support/InternalNames.h +++ b/flang/include/flang/Optimizer/Support/InternalNames.h @@ -156,6 +156,14 @@ struct NameUniquer { static std::string getTypeDescriptorBindingTableName(llvm::StringRef mangledTypeName); + /// Remove markers that have been added when doing partial type + /// conversions. mlir::Type cannot be mutated in a pass, so new + /// fir::RecordType must be created when lowering member types. + /// Suffixes added to these new types are meaningless and are + /// dropped in the names passed to LLVM. + static llvm::StringRef + dropTypeConversionMarkers(llvm::StringRef mangledTypeName); + private: static std::string intAsString(std::int64_t i); static std::string doKind(std::int64_t kind); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 92bc7246eca7005d21cbe36886f8a6307a64df05..6970da8698ae84dfd6f7c9bbfa20cbcf0449e6f0 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -10,6 +10,7 @@ #define FORTRAN_OPTIMIZER_TRANSFORMS_PASSES_H #include "flang/Optimizer/Dialect/FIROps.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassRegistry.h" #include @@ -83,6 +84,15 @@ std::unique_ptr createVScaleAttrPass(); std::unique_ptr createVScaleAttrPass(std::pair vscaleAttr); +struct FunctionAttrTypes { + mlir::LLVM::framePointerKind::FramePointerKind framePointerKind = + mlir::LLVM::framePointerKind::FramePointerKind::None; +}; + +std::unique_ptr createFunctionAttrPass(); +std::unique_ptr +createFunctionAttrPass(FunctionAttrTypes &functionAttr); + // declarative passes #define GEN_PASS_REGISTRATION #include "flang/Optimizer/Transforms/Passes.h.inc" diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index c3768fd2d689c1a11524995c74ec7ef625e33fd0..e3c45d41f04cc713845040c6ca3307a2110949fa 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -349,4 +349,25 @@ def VScaleAttr : Pass<"vscale-attr", "mlir::func::FuncOp"> { let constructor = "::fir::createVScaleAttrPass()"; } +def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { + let summary = "Pass that adds function attributes expected at LLVM IR level"; + let description = [{ This feature introduces a general attribute aimed at + customizing function characteristics. + Options include: + Add "frame-pointer" attribute to functions: Set an attribute for the frame + pointer on functions, to avoid saving the frame pointer in a register in + functions where it is unnecessary. This eliminates the need for + instructions to save, establish, and restore frame pointers, while also + freeing up an additional register in numerous functions. However, this + approach can make debugging unfeasible on certain machines. + }]; + let options = [ + Option<"framePointerKind", "frame-pointer", + "mlir::LLVM::framePointerKind::FramePointerKind", + /*default=*/"mlir::LLVM::framePointerKind::FramePointerKind{}", + "frame pointer">, + ]; + let constructor = "::fir::createFunctionAttrPass()"; +} + #endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 7c479a2334ea5553468b13580838b8959a09cc74..1defbf132327c44a2859153ccafcb32a8c979a58 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -301,8 +301,8 @@ public: NODE(parser, ErrLabel) NODE(parser, ErrorRecovery) NODE(parser, EventPostStmt) + NODE(parser, EventWaitSpec) NODE(parser, EventWaitStmt) - NODE(EventWaitStmt, EventWaitSpec) NODE(parser, ExecutableConstruct) NODE(parser, ExecutionPart) NODE(parser, ExecutionPartConstruct) @@ -462,6 +462,7 @@ public: NODE(NamelistStmt, Group) NODE(parser, NonLabelDoStmt) NODE(parser, NoPass) + NODE(parser, NotifyWaitStmt) NODE(parser, NullifyStmt) NODE(parser, NullInit) NODE(parser, ObjectDecl) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 393e0e24ec5cbd9ba7cdb0055bd6ad7e01748c1f..71195f2bb9ddc430bdac5991404c7eb6e7438174 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -209,11 +209,13 @@ struct ExitStmt; // R1156 struct GotoStmt; // R1157 struct ComputedGotoStmt; // R1158 struct StopStmt; // R1160, R1161 +struct NotifyWaitStmt; // F2023: R1166 struct SyncAllStmt; // R1164 struct SyncImagesStmt; // R1166 struct SyncMemoryStmt; // R1168 struct SyncTeamStmt; // R1169 struct EventPostStmt; // R1170, R1171 +struct EventWaitSpec; // F2023: R1177 struct EventWaitStmt; // R1172, R1173, R1174 struct FormTeamStmt; // R1175, R1176, R1177 struct LockStmt; // R1178 @@ -477,9 +479,9 @@ EMPTY_CLASS(FailImageStmt); // close-stmt | continue-stmt | cycle-stmt | deallocate-stmt | // endfile-stmt | error-stop-stmt | event-post-stmt | event-wait-stmt | // exit-stmt | fail-image-stmt | flush-stmt | form-team-stmt | -// goto-stmt | if-stmt | inquire-stmt | lock-stmt | nullify-stmt | -// open-stmt | pointer-assignment-stmt | print-stmt | read-stmt | -// return-stmt | rewind-stmt | stop-stmt | sync-all-stmt | +// goto-stmt | if-stmt | inquire-stmt | lock-stmt | notify-wait-stmt | +// nullify-stmt | open-stmt | pointer-assignment-stmt | print-stmt | +// read-stmt | return-stmt | rewind-stmt | stop-stmt | sync-all-stmt | // sync-images-stmt | sync-memory-stmt | sync-team-stmt | unlock-stmt | // wait-stmt | where-stmt | write-stmt | computed-goto-stmt | forall-stmt struct ActionStmt { @@ -494,8 +496,8 @@ struct ActionStmt { common::Indirection, common::Indirection, common::Indirection, common::Indirection, common::Indirection, common::Indirection, - common::Indirection, common::Indirection, - common::Indirection, + common::Indirection, common::Indirection, + common::Indirection, common::Indirection, common::Indirection, common::Indirection, common::Indirection, common::Indirection, common::Indirection, common::Indirection, @@ -2492,6 +2494,13 @@ struct StopStmt { std::tuple, std::optional> t; }; +// F2023: R1166 notify-wait-stmt -> NOTIFY WAIT ( notify-variable [, +// event-wait-spec-list] ) +struct NotifyWaitStmt { + TUPLE_CLASS_BOILERPLATE(NotifyWaitStmt); + std::tuple, std::list> t; +}; + // R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )] WRAPPER_CLASS(SyncAllStmt, std::list); @@ -2524,15 +2533,16 @@ struct EventPostStmt { std::tuple> t; }; +// R1173 event-wait-spec -> until-spec | sync-stat +struct EventWaitSpec { + UNION_CLASS_BOILERPLATE(EventWaitSpec); + std::variant u; +}; + // R1172 event-wait-stmt -> // EVENT WAIT ( event-variable [, event-wait-spec-list] ) -// R1173 event-wait-spec -> until-spec | sync-stat // R1174 until-spec -> UNTIL_COUNT = scalar-int-expr struct EventWaitStmt { - struct EventWaitSpec { - UNION_CLASS_BOILERPLATE(EventWaitSpec); - std::variant u; - }; TUPLE_CLASS_BOILERPLATE(EventWaitStmt); std::tuple> t; }; diff --git a/flang/include/flang/Runtime/allocatable.h b/flang/include/flang/Runtime/allocatable.h index 4169483398f6a74bf6e4c4fa1d33d07df183f433..58061d9862095ebc28048db8988b7eaefa1e1d12 100644 --- a/flang/include/flang/Runtime/allocatable.h +++ b/flang/include/flang/Runtime/allocatable.h @@ -26,22 +26,22 @@ extern "C" { // A descriptor must be initialized before being used for any purpose, // but needs reinitialization in a deallocated state only when there is // a change of type, rank, or corank. -void RTNAME(AllocatableInitIntrinsic)( +void RTDECL(AllocatableInitIntrinsic)( Descriptor &, TypeCategory, int kind, int rank = 0, int corank = 0); -void RTNAME(AllocatableInitCharacter)(Descriptor &, SubscriptValue length = 0, +void RTDECL(AllocatableInitCharacter)(Descriptor &, SubscriptValue length = 0, int kind = 1, int rank = 0, int corank = 0); -void RTNAME(AllocatableInitDerived)( +void RTDECL(AllocatableInitDerived)( Descriptor &, const typeInfo::DerivedType &, int rank = 0, int corank = 0); // Initializes the descriptor for an allocatable of intrinsic or derived type. // These functions are meant to be used in the allocate statement lowering. If // the descriptor is allocated, the initialization is skiped so the error // handling can be done by AllocatableAllocate. -void RTNAME(AllocatableInitIntrinsicForAllocate)( +void RTDECL(AllocatableInitIntrinsicForAllocate)( Descriptor &, TypeCategory, int kind, int rank = 0, int corank = 0); -void RTNAME(AllocatableInitCharacterForAllocate)(Descriptor &, +void RTDECL(AllocatableInitCharacterForAllocate)(Descriptor &, SubscriptValue length = 0, int kind = 1, int rank = 0, int corank = 0); -void RTNAME(AllocatableInitDerivedForAllocate)( +void RTDECL(AllocatableInitDerivedForAllocate)( Descriptor &, const typeInfo::DerivedType &, int rank = 0, int corank = 0); // Checks that an allocatable is not already allocated in statements @@ -50,29 +50,29 @@ void RTNAME(AllocatableInitDerivedForAllocate)( // (If there's no STAT=, the error will be caught later anyway, but // this API allows the error to be caught before descriptor is modified.) // Return 0 on success (deallocated state), else the STAT= value. -int RTNAME(AllocatableCheckAllocated)(Descriptor &, +int RTDECL(AllocatableCheckAllocated)(Descriptor &, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // For MOLD= allocation; sets bounds, cobounds, and length type // parameters from another descriptor. The destination descriptor must // be initialized and deallocated. -void RTNAME(AllocatableApplyMold)( +void RTDECL(AllocatableApplyMold)( Descriptor &, const Descriptor &mold, int rank = 0); // Explicitly sets the bounds and length type parameters of an initialized // deallocated allocatable. -void RTNAME(AllocatableSetBounds)( +void RTDECL(AllocatableSetBounds)( Descriptor &, int zeroBasedDim, SubscriptValue lower, SubscriptValue upper); // The upper cobound is ignored for the last codimension. -void RTNAME(AllocatableSetCoBounds)(Descriptor &, int zeroBasedCoDim, +void RTDECL(AllocatableSetCoBounds)(Descriptor &, int zeroBasedCoDim, SubscriptValue lower, SubscriptValue upper = 0); // Length type parameters are indexed in declaration order; i.e., 0 is the // first length type parameter in the deepest base type. (Not for use // with CHARACTER; see above.) -void RTNAME(AllocatableSetDerivedLength)( +void RTDECL(AllocatableSetDerivedLength)( Descriptor &, int which, SubscriptValue); // When an explicit type-spec appears in an ALLOCATE statement for an @@ -80,7 +80,7 @@ void RTNAME(AllocatableSetDerivedLength)( // a derived type or CHARACTER value, the explicit value has to match // the length type parameter's value. This API checks that requirement. // Returns 0 for success, or the STAT= value on failure with hasStat==true. -int RTNAME(AllocatableCheckLengthParameter)(Descriptor &, +int RTDECL(AllocatableCheckLengthParameter)(Descriptor &, int which /* 0 for CHARACTER length */, SubscriptValue other, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); @@ -94,10 +94,10 @@ int RTNAME(AllocatableCheckLengthParameter)(Descriptor &, // Successfully allocated memory is initialized if the allocatable has a // derived type, and is always initialized by AllocatableAllocateSource(). // Performs all necessary coarray synchronization and validation actions. -int RTNAME(AllocatableAllocate)(Descriptor &, bool hasStat = false, +int RTDECL(AllocatableAllocate)(Descriptor &, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); -int RTNAME(AllocatableAllocateSource)(Descriptor &, const Descriptor &source, +int RTDECL(AllocatableAllocateSource)(Descriptor &, const Descriptor &source, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); @@ -105,7 +105,7 @@ int RTNAME(AllocatableAllocateSource)(Descriptor &, const Descriptor &source, // but note the order of first two arguments is reversed for consistency // with the other APIs for allocatables.) The destination descriptor // must be initialized. -std::int32_t RTNAME(MoveAlloc)(Descriptor &to, Descriptor &from, +std::int32_t RTDECL(MoveAlloc)(Descriptor &to, Descriptor &from, const typeInfo::DerivedType *, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); @@ -113,19 +113,19 @@ std::int32_t RTNAME(MoveAlloc)(Descriptor &to, Descriptor &from, // Deallocates an allocatable. Finalizes elements &/or components as needed. // The allocatable is left in an initialized state suitable for reallocation // with the same bounds, cobounds, and length type parameters. -int RTNAME(AllocatableDeallocate)(Descriptor &, bool hasStat = false, +int RTDECL(AllocatableDeallocate)(Descriptor &, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // Same as AllocatableDeallocate but also set the dynamic type as the declared // type as mentioned in 7.3.2.3 note 7. -int RTNAME(AllocatableDeallocatePolymorphic)(Descriptor &, +int RTDECL(AllocatableDeallocatePolymorphic)(Descriptor &, const typeInfo::DerivedType *, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // Variant of above that does not finalize; for intermediate results -void RTNAME(AllocatableDeallocateNoFinal)( +void RTDECL(AllocatableDeallocateNoFinal)( Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Runtime/api-attrs.h b/flang/include/flang/Runtime/api-attrs.h index 61da2c06d3a4dc94a6b3cec65502c729a29e2e39..9c8a67ffc34a82fb08a837b5d04e8f148c715517 100644 --- a/flang/include/flang/Runtime/api-attrs.h +++ b/flang/include/flang/Runtime/api-attrs.h @@ -121,4 +121,15 @@ #undef RT_DEVICE_COMPILATION #endif +#if defined(__CUDACC__) +#define RT_DIAG_PUSH _Pragma("nv_diagnostic push") +#define RT_DIAG_POP _Pragma("nv_diagnostic pop") +#define RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN \ + _Pragma("nv_diag_suppress 20011") _Pragma("nv_diag_suppress 20014") +#else /* !defined(__CUDACC__) */ +#define RT_DIAG_PUSH +#define RT_DIAG_POP +#define RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN +#endif /* !defined(__CUDACC__) */ + #endif /* !FORTRAN_RUNTIME_API_ATTRS_H_ */ diff --git a/flang/include/flang/Runtime/array-constructor.h b/flang/include/flang/Runtime/array-constructor.h index 5274a2fc9e08c5c8b07fa2b23fbf054551a4bcb8..46fc0418c7991e4654823c46653845a98f44c783 100644 --- a/flang/include/flang/Runtime/array-constructor.h +++ b/flang/include/flang/Runtime/array-constructor.h @@ -21,15 +21,17 @@ namespace Fortran::runtime { // Runtime data structure to hold information about the storage of // an array constructor being constructed. struct ArrayConstructorVector { - ArrayConstructorVector(class Descriptor &to, SubscriptValue nextValuePosition, - SubscriptValue actualAllocationSize, const char *sourceFile, - int sourceLine, bool useValueLengthParameters) + RT_API_ATTRS ArrayConstructorVector(class Descriptor &to, + SubscriptValue nextValuePosition, SubscriptValue actualAllocationSize, + const char *sourceFile, int sourceLine, bool useValueLengthParameters) : to{to}, nextValuePosition{nextValuePosition}, actualAllocationSize{actualAllocationSize}, sourceFile{sourceFile}, - sourceLine{sourceLine}, useValueLengthParameters_{ - useValueLengthParameters} {} + sourceLine{sourceLine}, + useValueLengthParameters_{useValueLengthParameters} {} - bool useValueLengthParameters() const { return useValueLengthParameters_; } + RT_API_ATTRS bool useValueLengthParameters() const { + return useValueLengthParameters_; + } class Descriptor &to; SubscriptValue nextValuePosition; @@ -95,13 +97,13 @@ extern "C" { // the target the runtime is compiled for). This avoids the need for the runtime // to maintain a state, or to use dynamic allocation for it. "vectorClassSize" // is used to validate that lowering allocated enough space for it. -void RTNAME(InitArrayConstructorVector)(ArrayConstructorVector &vector, +void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector, Descriptor &to, bool useValueLengthParameters, int vectorClassSize, const char *sourceFile = nullptr, int sourceLine = 0); // Generic API to push any kind of entity into the array constructor (any // Fortran type and any rank). -void RTNAME(PushArrayConstructorValue)( +void RTDECL(PushArrayConstructorValue)( ArrayConstructorVector &vector, const Descriptor &from); // API to push scalar array constructor value of: @@ -109,7 +111,7 @@ void RTNAME(PushArrayConstructorValue)( // - or a derived type that has no length parameters, and no allocatable // component (that would require deep copies). // It requires no descriptor for the value that is passed via its base address. -void RTNAME(PushArrayConstructorSimpleScalar)( +void RTDECL(PushArrayConstructorSimpleScalar)( ArrayConstructorVector &vector, void *from); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Runtime/character.h b/flang/include/flang/Runtime/character.h index 768de75b639c554c93a8505099330485648d9fe9..dd47686fe858fd5cc7bf39a215ab0b2ec677b63c 100644 --- a/flang/include/flang/Runtime/character.h +++ b/flang/include/flang/Runtime/character.h @@ -20,14 +20,16 @@ namespace Fortran::runtime { class Descriptor; template -int CharacterScalarCompare( +RT_API_ATTRS int CharacterScalarCompare( const CHAR *x, const CHAR *y, std::size_t xChars, std::size_t yChars); -extern template int CharacterScalarCompare( +extern template RT_API_ATTRS int CharacterScalarCompare( const char *x, const char *y, std::size_t xChars, std::size_t yChars); -extern template int CharacterScalarCompare(const char16_t *x, - const char16_t *y, std::size_t xChars, std::size_t yChars); -extern template int CharacterScalarCompare(const char32_t *x, - const char32_t *y, std::size_t xChars, std::size_t yChars); +extern template RT_API_ATTRS int CharacterScalarCompare( + const char16_t *x, const char16_t *y, std::size_t xChars, + std::size_t yChars); +extern template RT_API_ATTRS int CharacterScalarCompare( + const char32_t *x, const char32_t *y, std::size_t xChars, + std::size_t yChars); extern "C" { @@ -36,12 +38,12 @@ extern "C" { // initialized CHARACTER allocatable scalar or array descriptor -- use // AllocatableInitCharacter() to set one up. Crashes when not // conforming. Assumes independence of data. -void RTNAME(CharacterConcatenate)(Descriptor &accumulator, +void RTDECL(CharacterConcatenate)(Descriptor &accumulator, const Descriptor &from, const char *sourceFile = nullptr, int sourceLine = 0); // Convenience specialization for ASCII scalars concatenation. -void RTNAME(CharacterConcatenateScalar1)( +void RTDECL(CharacterConcatenateScalar1)( Descriptor &accumulator, const char *from, std::size_t chars); // CHARACTER comparisons. The kinds must match. Like std::memcmp(), @@ -52,77 +54,77 @@ void RTNAME(CharacterConcatenateScalar1)( // N.B.: Calls to the restricted specific intrinsic functions LGE, LGT, LLE, // & LLT are converted into calls to these during lowering; they don't have // to be able to be passed as actual procedure arguments. -int RTNAME(CharacterCompareScalar)(const Descriptor &, const Descriptor &); -int RTNAME(CharacterCompareScalar1)( +int RTDECL(CharacterCompareScalar)(const Descriptor &, const Descriptor &); +int RTDECL(CharacterCompareScalar1)( const char *x, const char *y, std::size_t xChars, std::size_t yChars); -int RTNAME(CharacterCompareScalar2)(const char16_t *x, const char16_t *y, +int RTDECL(CharacterCompareScalar2)(const char16_t *x, const char16_t *y, std::size_t xChars, std::size_t yChars); -int RTNAME(CharacterCompareScalar4)(const char32_t *x, const char32_t *y, +int RTDECL(CharacterCompareScalar4)(const char32_t *x, const char32_t *y, std::size_t xChars, std::size_t yChars); // General CHARACTER comparison; the result is a LOGICAL(KIND=1) array that // is established and populated. -void RTNAME(CharacterCompare)( +void RTDECL(CharacterCompare)( Descriptor &result, const Descriptor &, const Descriptor &); // Special-case support for optimized ASCII scalar expressions. // Copies data from 'rhs' to the remaining space (lhsLength - offset) // in 'lhs', if any. Returns the new offset. Assumes independence. -std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes, +std::size_t RTDECL(CharacterAppend1)(char *lhs, std::size_t lhsBytes, std::size_t offset, const char *rhs, std::size_t rhsBytes); // Appends any necessary spaces to a CHARACTER(KIND=1) scalar. -void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset); +void RTDECL(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset); // Intrinsic functions // The result descriptors below are all established by the runtime. -void RTNAME(Adjustl)(Descriptor &result, const Descriptor &, +void RTDECL(Adjustl)(Descriptor &result, const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); -void RTNAME(Adjustr)(Descriptor &result, const Descriptor &, +void RTDECL(Adjustr)(Descriptor &result, const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); -std::size_t RTNAME(LenTrim1)(const char *, std::size_t); -std::size_t RTNAME(LenTrim2)(const char16_t *, std::size_t); -std::size_t RTNAME(LenTrim4)(const char32_t *, std::size_t); -void RTNAME(LenTrim)(Descriptor &result, const Descriptor &, int kind, +std::size_t RTDECL(LenTrim1)(const char *, std::size_t); +std::size_t RTDECL(LenTrim2)(const char16_t *, std::size_t); +std::size_t RTDECL(LenTrim4)(const char32_t *, std::size_t); +void RTDECL(LenTrim)(Descriptor &result, const Descriptor &, int kind, const char *sourceFile = nullptr, int sourceLine = 0); -void RTNAME(Repeat)(Descriptor &result, const Descriptor &string, +void RTDECL(Repeat)(Descriptor &result, const Descriptor &string, std::int64_t ncopies, const char *sourceFile = nullptr, int sourceLine = 0); -void RTNAME(Trim)(Descriptor &result, const Descriptor &string, +void RTDECL(Trim)(Descriptor &result, const Descriptor &string, const char *sourceFile = nullptr, int sourceLine = 0); -void RTNAME(CharacterMax)(Descriptor &accumulator, const Descriptor &x, +void RTDECL(CharacterMax)(Descriptor &accumulator, const Descriptor &x, const char *sourceFile = nullptr, int sourceLine = 0); -void RTNAME(CharacterMin)(Descriptor &accumulator, const Descriptor &x, +void RTDECL(CharacterMin)(Descriptor &accumulator, const Descriptor &x, const char *sourceFile = nullptr, int sourceLine = 0); -std::size_t RTNAME(Index1)(const char *, std::size_t, const char *substring, +std::size_t RTDECL(Index1)(const char *, std::size_t, const char *substring, std::size_t, bool back = false); -std::size_t RTNAME(Index2)(const char16_t *, std::size_t, +std::size_t RTDECL(Index2)(const char16_t *, std::size_t, const char16_t *substring, std::size_t, bool back = false); -std::size_t RTNAME(Index4)(const char32_t *, std::size_t, +std::size_t RTDECL(Index4)(const char32_t *, std::size_t, const char32_t *substring, std::size_t, bool back = false); -void RTNAME(Index)(Descriptor &result, const Descriptor &string, +void RTDECL(Index)(Descriptor &result, const Descriptor &string, const Descriptor &substring, const Descriptor *back /*can be null*/, int kind, const char *sourceFile = nullptr, int sourceLine = 0); -std::size_t RTNAME(Scan1)( +std::size_t RTDECL(Scan1)( const char *, std::size_t, const char *set, std::size_t, bool back = false); -std::size_t RTNAME(Scan2)(const char16_t *, std::size_t, const char16_t *set, +std::size_t RTDECL(Scan2)(const char16_t *, std::size_t, const char16_t *set, std::size_t, bool back = false); -std::size_t RTNAME(Scan4)(const char32_t *, std::size_t, const char32_t *set, +std::size_t RTDECL(Scan4)(const char32_t *, std::size_t, const char32_t *set, std::size_t, bool back = false); -void RTNAME(Scan)(Descriptor &result, const Descriptor &string, +void RTDECL(Scan)(Descriptor &result, const Descriptor &string, const Descriptor &set, const Descriptor *back /*can be null*/, int kind, const char *sourceFile = nullptr, int sourceLine = 0); -std::size_t RTNAME(Verify1)( +std::size_t RTDECL(Verify1)( const char *, std::size_t, const char *set, std::size_t, bool back = false); -std::size_t RTNAME(Verify2)(const char16_t *, std::size_t, const char16_t *set, +std::size_t RTDECL(Verify2)(const char16_t *, std::size_t, const char16_t *set, std::size_t, bool back = false); -std::size_t RTNAME(Verify4)(const char32_t *, std::size_t, const char32_t *set, +std::size_t RTDECL(Verify4)(const char32_t *, std::size_t, const char32_t *set, std::size_t, bool back = false); -void RTNAME(Verify)(Descriptor &result, const Descriptor &string, +void RTDECL(Verify)(Descriptor &result, const Descriptor &string, const Descriptor &set, const Descriptor *back /*can be null*/, int kind, const char *sourceFile = nullptr, int sourceLine = 0); } diff --git a/flang/include/flang/Runtime/derived-api.h b/flang/include/flang/Runtime/derived-api.h index decba9f686d92015c7f01c011260bdbf07bd4aaf..79aa7d82de8819230de37f5a351c54183c838b12 100644 --- a/flang/include/flang/Runtime/derived-api.h +++ b/flang/include/flang/Runtime/derived-api.h @@ -29,37 +29,37 @@ extern "C" { // Initializes and allocates an object's components, if it has a derived type // with any default component initialization or automatic components. // The descriptor must be initialized and non-null. -void RTNAME(Initialize)( +void RTDECL(Initialize)( const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); // Finalizes an object and its components. Deallocates any // allocatable/automatic components. Does not deallocate the descriptor's // storage. -void RTNAME(Destroy)(const Descriptor &); +void RTDECL(Destroy)(const Descriptor &); // Finalizes the object and its components. -void RTNAME(Finalize)( +void RTDECL(Finalize)( const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); /// Deallocates any allocatable/automatic components. /// Does not deallocate the descriptor's storage. /// Does not perform any finalization. -void RTNAME(DestroyWithoutFinalization)(const Descriptor &); +void RTDECL(DestroyWithoutFinalization)(const Descriptor &); // Intrinsic or defined assignment, with scalar expansion but not type // conversion. -void RTNAME(Assign)(const Descriptor &, const Descriptor &, +void RTDECL(Assign)(const Descriptor &, const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); // Perform the test of the CLASS IS type guard statement of the SELECT TYPE // construct. -bool RTNAME(ClassIs)(const Descriptor &, const typeInfo::DerivedType &); +bool RTDECL(ClassIs)(const Descriptor &, const typeInfo::DerivedType &); // Perform the test of the SAME_TYPE_AS intrinsic. -bool RTNAME(SameTypeAs)(const Descriptor &, const Descriptor &); +bool RTDECL(SameTypeAs)(const Descriptor &, const Descriptor &); // Perform the test of the EXTENDS_TYPE_OF intrinsic. -bool RTNAME(ExtendsTypeOf)(const Descriptor &, const Descriptor &); +bool RTDECL(ExtendsTypeOf)(const Descriptor &, const Descriptor &); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Runtime/descriptor.h b/flang/include/flang/Runtime/descriptor.h index fa68d97769695a2c0d14bb6cc0fd839b10f2f7ae..e36b37c1a917eb3c64abbbeb808c9b2eeafd30b8 100644 --- a/flang/include/flang/Runtime/descriptor.h +++ b/flang/include/flang/Runtime/descriptor.h @@ -67,16 +67,16 @@ public: } // Do not use this API to cause the LB of an empty dimension // to be anything other than 1. Use SetBounds() instead if you can. - Dimension &SetLowerBound(SubscriptValue lower) { + RT_API_ATTRS Dimension &SetLowerBound(SubscriptValue lower) { raw_.lower_bound = lower; return *this; } - Dimension &SetUpperBound(SubscriptValue upper) { + RT_API_ATTRS Dimension &SetUpperBound(SubscriptValue upper) { auto lower{raw_.lower_bound}; raw_.extent = upper >= lower ? upper - lower + 1 : 0; return *this; } - Dimension &SetExtent(SubscriptValue extent) { + RT_API_ATTRS Dimension &SetExtent(SubscriptValue extent) { raw_.extent = extent; return *this; } @@ -467,5 +467,6 @@ public: private: char storage_[byteSize]{}; }; + } // namespace Fortran::runtime #endif // FORTRAN_RUNTIME_DESCRIPTOR_H_ diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h index ad592814e5acb79581527caec29a7a2b38880629..175113c57ccb52a9e1d7e0a41ae171b82c1e2cf8 100644 --- a/flang/include/flang/Runtime/extensions.h +++ b/flang/include/flang/Runtime/extensions.h @@ -14,6 +14,7 @@ #define FORTRAN_PROCEDURE_NAME(name) name##_ +#include #include extern "C" { @@ -28,5 +29,8 @@ std::int32_t FORTRAN_PROCEDURE_NAME(iargc)(); void FORTRAN_PROCEDURE_NAME(getarg)( std::int32_t &n, std::int8_t *arg, std::int64_t length); +// GNU extension subroutine GETLOG(C). +void FORTRAN_PROCEDURE_NAME(getlog)(std::byte *name, std::int64_t length); + } // extern "C" #endif // FORTRAN_RUNTIME_EXTENSIONS_H_ diff --git a/flang/include/flang/Runtime/inquiry.h b/flang/include/flang/Runtime/inquiry.h index 8d673637b30092e1d4b1b1da4a9e9bb43459e6d3..3fe670b0fae31ebad214e810a564a03df51c5cf6 100644 --- a/flang/include/flang/Runtime/inquiry.h +++ b/flang/include/flang/Runtime/inquiry.h @@ -21,13 +21,13 @@ class Descriptor; extern "C" { -std::int64_t RTNAME(LboundDim)(const Descriptor &array, int dim, +std::int64_t RTDECL(LboundDim)(const Descriptor &array, int dim, const char *sourceFile = nullptr, int line = 0); -void RTNAME(Ubound)(Descriptor &result, const Descriptor &array, int kind, +void RTDECL(Ubound)(Descriptor &result, const Descriptor &array, int kind, const char *sourceFile = nullptr, int line = 0); -std::int64_t RTNAME(Size)( +std::int64_t RTDECL(Size)( const Descriptor &array, const char *sourceFile = nullptr, int line = 0); -std::int64_t RTNAME(SizeDim)(const Descriptor &array, int dim, +std::int64_t RTDECL(SizeDim)(const Descriptor &array, int dim, const char *sourceFile = nullptr, int line = 0); } // extern "C" diff --git a/flang/include/flang/Runtime/io-api.h b/flang/include/flang/Runtime/io-api.h index 41574e3bb80ad3b46bb250d1cad995803d449a1d..0277f0ea9e97e31740d9259aa90d59af6c066f73 100644 --- a/flang/include/flang/Runtime/io-api.h +++ b/flang/include/flang/Runtime/io-api.h @@ -14,6 +14,7 @@ #include "flang/Common/uint128.h" #include "flang/Runtime/entry-names.h" #include "flang/Runtime/iostat.h" +#include "flang/Runtime/magic-numbers.h" #include #include @@ -29,7 +30,9 @@ class IoStatementState; using Cookie = IoStatementState *; using ExternalUnit = int; using AsynchronousId = int; -static constexpr ExternalUnit DefaultUnit{-1}; // READ(*), WRITE(*), PRINT + +static constexpr ExternalUnit DefaultOutputUnit{FORTRAN_DEFAULT_OUTPUT_UNIT}; +static constexpr ExternalUnit DefaultInputUnit{FORTRAN_DEFAULT_INPUT_UNIT}; // INQUIRE specifiers are encoded as simple base-26 packings of // the spellings of their keywords. @@ -57,7 +60,8 @@ extern "C" { // These functions initiate data transfer statements (READ, WRITE, PRINT). // Example: PRINT *, 666 is implemented as the series of calls: -// Cookie cookie{BeginExternalListOutput(DefaultUnit,__FILE__,__LINE__)}; +// Cookie cookie{BeginExternalListOutput(DefaultOutputUnit, +// __FILE__, __LINE__)}; // OutputInteger32(cookie, 666); // EndIoStatement(cookie); // Formatted I/O with explicit formats can supply the format as a @@ -135,19 +139,21 @@ enum Iostat IONAME(CheckUnitNumberInRange128)(common::int128_t unit, const char *sourceFile = nullptr, int sourceLine = 0); // External synchronous I/O initiation -Cookie IONAME(BeginExternalListOutput)(ExternalUnit = DefaultUnit, +Cookie IONAME(BeginExternalListOutput)(ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IONAME(BeginExternalListInput)(ExternalUnit = DefaultUnit, +Cookie IONAME(BeginExternalListInput)(ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr, int sourceLine = 0); Cookie IONAME(BeginExternalFormattedOutput)(const char *format, std::size_t, - const Descriptor *formatDescriptor = nullptr, ExternalUnit = DefaultUnit, - const char *sourceFile = nullptr, int sourceLine = 0); + const Descriptor *formatDescriptor = nullptr, + ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr, + int sourceLine = 0); Cookie IONAME(BeginExternalFormattedInput)(const char *format, std::size_t, - const Descriptor *formatDescriptor = nullptr, ExternalUnit = DefaultUnit, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IONAME(BeginUnformattedOutput)(ExternalUnit = DefaultUnit, + const Descriptor *formatDescriptor = nullptr, + ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IONAME(BeginUnformattedOutput)(ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IONAME(BeginUnformattedInput)(ExternalUnit = DefaultUnit, +Cookie IONAME(BeginUnformattedInput)(ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr, int sourceLine = 0); // WAIT(ID=) @@ -190,7 +196,7 @@ Cookie IONAME(BeginInquireIoLength)( // This call makes the runtime library defer those particular error/end // conditions to the EndIoStatement() call rather than terminating // the image. E.g., for READ(*,*,END=666) A, B, (C(J),J=1,N) -// Cookie cookie{BeginExternalListInput(DefaultUnit,__FILE__,__LINE__)}; +// Cookie cookie{BeginExternalListInput(DefaultInputUnit,__FILE__,__LINE__)}; // EnableHandlers(cookie, false, false, true /*END=*/, false); // if (InputReal64(cookie, &A)) { // if (InputReal64(cookie, &B)) { diff --git a/flang/include/flang/Runtime/magic-numbers.h b/flang/include/flang/Runtime/magic-numbers.h index d00d5027d4ed27236bd66bb1493f748b96b9e7f6..196b13ad3755b3b45a4654061e14a4627a15961f 100644 --- a/flang/include/flang/Runtime/magic-numbers.h +++ b/flang/include/flang/Runtime/magic-numbers.h @@ -27,6 +27,10 @@ start at 100 so as to never conflict with those codes. #ifndef FORTRAN_RUNTIME_MAGIC_NUMBERS_H_ #define FORTRAN_RUNTIME_MAGIC_NUMBERS_H_ +#define FORTRAN_DEFAULT_OUTPUT_UNIT 6 +#define FORTRAN_DEFAULT_INPUT_UNIT 5 +#define FORTRAN_ERROR_UNIT 0 + #define FORTRAN_RUNTIME_IOSTAT_END (-1) #define FORTRAN_RUNTIME_IOSTAT_EOR (-2) #define FORTRAN_RUNTIME_IOSTAT_FLUSH (-3) diff --git a/flang/include/flang/Runtime/matmul-transpose.h b/flang/include/flang/Runtime/matmul-transpose.h index 7cfb189863df82be2ee0d7958aa6c05d1ac17d3c..5eb5896972e0fd3c31d28c01a4c6e3b71b89b89f 100644 --- a/flang/include/flang/Runtime/matmul-transpose.h +++ b/flang/include/flang/Runtime/matmul-transpose.h @@ -18,12 +18,12 @@ extern "C" { // The most general MATMUL(TRANSPOSE()). All type and shape information is // taken from the arguments' descriptors, and the result is dynamically // allocated. -void RTNAME(MatmulTranspose)(Descriptor &, const Descriptor &, +void RTDECL(MatmulTranspose)(Descriptor &, const Descriptor &, const Descriptor &, const char *sourceFile = nullptr, int line = 0); // A non-allocating variant; the result's descriptor must be established // and have a valid base address. -void RTNAME(MatmulTransposeDirect)(const Descriptor &, const Descriptor &, +void RTDECL(MatmulTransposeDirect)(const Descriptor &, const Descriptor &, const Descriptor &, const char *sourceFile = nullptr, int line = 0); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Runtime/matmul.h b/flang/include/flang/Runtime/matmul.h index 4598c487a12ca1a409ac5551e4780a6959a660f3..40581d44de9e2c983fc66aa9d8b1ae203a8a2795 100644 --- a/flang/include/flang/Runtime/matmul.h +++ b/flang/include/flang/Runtime/matmul.h @@ -17,12 +17,12 @@ extern "C" { // The most general MATMUL. All type and shape information is taken from the // arguments' descriptors, and the result is dynamically allocated. -void RTNAME(Matmul)(Descriptor &, const Descriptor &, const Descriptor &, +void RTDECL(Matmul)(Descriptor &, const Descriptor &, const Descriptor &, const char *sourceFile = nullptr, int line = 0); // A non-allocating variant; the result's descriptor must be established // and have a valid base address. -void RTNAME(MatmulDirect)(const Descriptor &, const Descriptor &, +void RTDECL(MatmulDirect)(const Descriptor &, const Descriptor &, const Descriptor &, const char *sourceFile = nullptr, int line = 0); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Runtime/memory.h b/flang/include/flang/Runtime/memory.h index bde056f439a5ee74ed080ab46aa8ef69da6950fc..e24c509f4e90cbe23998bec73cd4bd4368ecf29a 100644 --- a/flang/include/flang/Runtime/memory.h +++ b/flang/include/flang/Runtime/memory.h @@ -23,14 +23,17 @@ class Terminator; [[nodiscard]] RT_API_ATTRS void *AllocateMemoryOrCrash( const Terminator &, std::size_t bytes); -template [[nodiscard]] A &AllocateOrCrash(const Terminator &t) { +template +[[nodiscard]] RT_API_ATTRS A &AllocateOrCrash(const Terminator &t) { return *reinterpret_cast(AllocateMemoryOrCrash(t, sizeof(A))); } +RT_API_ATTRS void *ReallocateMemoryOrCrash( + const Terminator &, void *ptr, std::size_t newByteSize); RT_API_ATTRS void FreeMemory(void *); template RT_API_ATTRS void FreeMemory(A *p) { FreeMemory(reinterpret_cast(p)); } -template void FreeMemoryAndNullify(A *&p) { +template RT_API_ATTRS void FreeMemoryAndNullify(A *&p) { FreeMemory(p); p = nullptr; } diff --git a/flang/include/flang/Runtime/misc-intrinsic.h b/flang/include/flang/Runtime/misc-intrinsic.h index d4c20539532d4b2007b786de2bee4eb8ca156463..73cc9e2023d979aea6fa1da6f2c4b1cfb01abd3b 100644 --- a/flang/include/flang/Runtime/misc-intrinsic.h +++ b/flang/include/flang/Runtime/misc-intrinsic.h @@ -19,9 +19,9 @@ namespace Fortran::runtime { class Descriptor; extern "C" { -void RTNAME(Transfer)(Descriptor &result, const Descriptor &source, +void RTDECL(Transfer)(Descriptor &result, const Descriptor &source, const Descriptor &mold, const char *sourceFile, int line); -void RTNAME(TransferSize)(Descriptor &result, const Descriptor &source, +void RTDECL(TransferSize)(Descriptor &result, const Descriptor &source, const Descriptor &mold, const char *sourceFile, int line, std::int64_t size); } // extern "C" diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h index e4e11a61731a613d3969eb1c4a7862ac7a1d5b16..3d9cb8b5b0acdc0a7bff5b99c8ed15c40c96e0e6 100644 --- a/flang/include/flang/Runtime/numeric.h +++ b/flang/include/flang/Runtime/numeric.h @@ -20,280 +20,280 @@ namespace Fortran::runtime { extern "C" { // CEILING -CppTypeFor RTNAME(Ceiling4_1)( +CppTypeFor RTDECL(Ceiling4_1)( CppTypeFor); -CppTypeFor RTNAME(Ceiling4_2)( +CppTypeFor RTDECL(Ceiling4_2)( CppTypeFor); -CppTypeFor RTNAME(Ceiling4_4)( +CppTypeFor RTDECL(Ceiling4_4)( CppTypeFor); -CppTypeFor RTNAME(Ceiling4_8)( +CppTypeFor RTDECL(Ceiling4_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Ceiling4_16)( +CppTypeFor RTDECL(Ceiling4_16)( CppTypeFor); #endif -CppTypeFor RTNAME(Ceiling8_1)( +CppTypeFor RTDECL(Ceiling8_1)( CppTypeFor); -CppTypeFor RTNAME(Ceiling8_2)( +CppTypeFor RTDECL(Ceiling8_2)( CppTypeFor); -CppTypeFor RTNAME(Ceiling8_4)( +CppTypeFor RTDECL(Ceiling8_4)( CppTypeFor); -CppTypeFor RTNAME(Ceiling8_8)( +CppTypeFor RTDECL(Ceiling8_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Ceiling8_16)( +CppTypeFor RTDECL(Ceiling8_16)( CppTypeFor); #endif #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Ceiling10_1)( +CppTypeFor RTDECL(Ceiling10_1)( CppTypeFor); -CppTypeFor RTNAME(Ceiling10_2)( +CppTypeFor RTDECL(Ceiling10_2)( CppTypeFor); -CppTypeFor RTNAME(Ceiling10_4)( +CppTypeFor RTDECL(Ceiling10_4)( CppTypeFor); -CppTypeFor RTNAME(Ceiling10_8)( +CppTypeFor RTDECL(Ceiling10_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Ceiling10_16)( +CppTypeFor RTDECL(Ceiling10_16)( CppTypeFor); #endif #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Ceiling16_1)( +CppTypeFor RTDECL(Ceiling16_1)( CppTypeFor); -CppTypeFor RTNAME(Ceiling16_2)( +CppTypeFor RTDECL(Ceiling16_2)( CppTypeFor); -CppTypeFor RTNAME(Ceiling16_4)( +CppTypeFor RTDECL(Ceiling16_4)( CppTypeFor); -CppTypeFor RTNAME(Ceiling16_8)( +CppTypeFor RTDECL(Ceiling16_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Ceiling16_16)( +CppTypeFor RTDECL(Ceiling16_16)( CppTypeFor); #endif #endif // EXPONENT is defined to return default INTEGER; support INTEGER(4 & 8) -CppTypeFor RTNAME(Exponent4_4)( +CppTypeFor RTDECL(Exponent4_4)( CppTypeFor); -CppTypeFor RTNAME(Exponent4_8)( +CppTypeFor RTDECL(Exponent4_8)( CppTypeFor); -CppTypeFor RTNAME(Exponent8_4)( +CppTypeFor RTDECL(Exponent8_4)( CppTypeFor); -CppTypeFor RTNAME(Exponent8_8)( +CppTypeFor RTDECL(Exponent8_8)( CppTypeFor); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Exponent10_4)( +CppTypeFor RTDECL(Exponent10_4)( CppTypeFor); -CppTypeFor RTNAME(Exponent10_8)( +CppTypeFor RTDECL(Exponent10_8)( CppTypeFor); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT -CppTypeFor RTNAME(Exponent16_4)( +CppTypeFor RTDECL(Exponent16_4)( CppTypeFor); -CppTypeFor RTNAME(Exponent16_8)( +CppTypeFor RTDECL(Exponent16_8)( CppTypeFor); #endif // FLOOR -CppTypeFor RTNAME(Floor4_1)( +CppTypeFor RTDECL(Floor4_1)( CppTypeFor); -CppTypeFor RTNAME(Floor4_2)( +CppTypeFor RTDECL(Floor4_2)( CppTypeFor); -CppTypeFor RTNAME(Floor4_4)( +CppTypeFor RTDECL(Floor4_4)( CppTypeFor); -CppTypeFor RTNAME(Floor4_8)( +CppTypeFor RTDECL(Floor4_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Floor4_16)( +CppTypeFor RTDECL(Floor4_16)( CppTypeFor); #endif -CppTypeFor RTNAME(Floor8_1)( +CppTypeFor RTDECL(Floor8_1)( CppTypeFor); -CppTypeFor RTNAME(Floor8_2)( +CppTypeFor RTDECL(Floor8_2)( CppTypeFor); -CppTypeFor RTNAME(Floor8_4)( +CppTypeFor RTDECL(Floor8_4)( CppTypeFor); -CppTypeFor RTNAME(Floor8_8)( +CppTypeFor RTDECL(Floor8_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Floor8_16)( +CppTypeFor RTDECL(Floor8_16)( CppTypeFor); #endif #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Floor10_1)( +CppTypeFor RTDECL(Floor10_1)( CppTypeFor); -CppTypeFor RTNAME(Floor10_2)( +CppTypeFor RTDECL(Floor10_2)( CppTypeFor); -CppTypeFor RTNAME(Floor10_4)( +CppTypeFor RTDECL(Floor10_4)( CppTypeFor); -CppTypeFor RTNAME(Floor10_8)( +CppTypeFor RTDECL(Floor10_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Floor10_16)( +CppTypeFor RTDECL(Floor10_16)( CppTypeFor); #endif #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Floor16_1)( +CppTypeFor RTDECL(Floor16_1)( CppTypeFor); -CppTypeFor RTNAME(Floor16_2)( +CppTypeFor RTDECL(Floor16_2)( CppTypeFor); -CppTypeFor RTNAME(Floor16_4)( +CppTypeFor RTDECL(Floor16_4)( CppTypeFor); -CppTypeFor RTNAME(Floor16_8)( +CppTypeFor RTDECL(Floor16_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Floor16_16)( +CppTypeFor RTDECL(Floor16_16)( CppTypeFor); #endif #endif // FRACTION -CppTypeFor RTNAME(Fraction4)( +CppTypeFor RTDECL(Fraction4)( CppTypeFor); -CppTypeFor RTNAME(Fraction8)( +CppTypeFor RTDECL(Fraction8)( CppTypeFor); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Fraction10)( +CppTypeFor RTDECL(Fraction10)( CppTypeFor); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Fraction16)( +CppTypeFor RTDECL(Fraction16)( CppTypeFor); #endif // ISNAN / IEEE_IS_NAN -bool RTNAME(IsNaN4)(CppTypeFor); -bool RTNAME(IsNaN8)(CppTypeFor); +bool RTDECL(IsNaN4)(CppTypeFor); +bool RTDECL(IsNaN8)(CppTypeFor); #if LDBL_MANT_DIG == 64 -bool RTNAME(IsNaN10)(CppTypeFor); +bool RTDECL(IsNaN10)(CppTypeFor); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -bool RTNAME(IsNaN16)(CppTypeFor); +bool RTDECL(IsNaN16)(CppTypeFor); #endif // MOD & MODULO -CppTypeFor RTNAME(ModInteger1)( +CppTypeFor RTDECL(ModInteger1)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModInteger2)( +CppTypeFor RTDECL(ModInteger2)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModInteger4)( +CppTypeFor RTDECL(ModInteger4)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModInteger8)( +CppTypeFor RTDECL(ModInteger8)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(ModInteger16)( +CppTypeFor RTDECL(ModInteger16)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #endif -CppTypeFor RTNAME(ModReal4)( +CppTypeFor RTDECL(ModReal4)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModReal8)( +CppTypeFor RTDECL(ModReal8)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(ModReal10)( +CppTypeFor RTDECL(ModReal10)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(ModReal16)( +CppTypeFor RTDECL(ModReal16)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #endif -CppTypeFor RTNAME(ModuloInteger1)( +CppTypeFor RTDECL(ModuloInteger1)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModuloInteger2)( +CppTypeFor RTDECL(ModuloInteger2)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModuloInteger4)( +CppTypeFor RTDECL(ModuloInteger4)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModuloInteger8)( +CppTypeFor RTDECL(ModuloInteger8)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(ModuloInteger16)( +CppTypeFor RTDECL(ModuloInteger16)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #endif -CppTypeFor RTNAME(ModuloReal4)( +CppTypeFor RTDECL(ModuloReal4)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); -CppTypeFor RTNAME(ModuloReal8)( +CppTypeFor RTDECL(ModuloReal8)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(ModuloReal10)( +CppTypeFor RTDECL(ModuloReal10)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(ModuloReal16)( +CppTypeFor RTDECL(ModuloReal16)( CppTypeFor, CppTypeFor, const char *sourceFile = nullptr, int sourceLine = 0); #endif // NINT -CppTypeFor RTNAME(Nint4_1)( +CppTypeFor RTDECL(Nint4_1)( CppTypeFor); -CppTypeFor RTNAME(Nint4_2)( +CppTypeFor RTDECL(Nint4_2)( CppTypeFor); -CppTypeFor RTNAME(Nint4_4)( +CppTypeFor RTDECL(Nint4_4)( CppTypeFor); -CppTypeFor RTNAME(Nint4_8)( +CppTypeFor RTDECL(Nint4_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Nint4_16)( +CppTypeFor RTDECL(Nint4_16)( CppTypeFor); #endif -CppTypeFor RTNAME(Nint8_1)( +CppTypeFor RTDECL(Nint8_1)( CppTypeFor); -CppTypeFor RTNAME(Nint8_2)( +CppTypeFor RTDECL(Nint8_2)( CppTypeFor); -CppTypeFor RTNAME(Nint8_4)( +CppTypeFor RTDECL(Nint8_4)( CppTypeFor); -CppTypeFor RTNAME(Nint8_8)( +CppTypeFor RTDECL(Nint8_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Nint8_16)( +CppTypeFor RTDECL(Nint8_16)( CppTypeFor); #endif #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Nint10_1)( +CppTypeFor RTDECL(Nint10_1)( CppTypeFor); -CppTypeFor RTNAME(Nint10_2)( +CppTypeFor RTDECL(Nint10_2)( CppTypeFor); -CppTypeFor RTNAME(Nint10_4)( +CppTypeFor RTDECL(Nint10_4)( CppTypeFor); -CppTypeFor RTNAME(Nint10_8)( +CppTypeFor RTDECL(Nint10_8)( CppTypeFor); #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(Nint10_16)( +CppTypeFor RTDECL(Nint10_16)( CppTypeFor); #endif #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Nint16_1)( +CppTypeFor RTDECL(Nint16_1)( CppTypeFor); -CppTypeFor RTNAME(Nint16_2)( +CppTypeFor RTDECL(Nint16_2)( CppTypeFor); -CppTypeFor RTNAME(Nint16_4)( +CppTypeFor RTDECL(Nint16_4)( CppTypeFor); -CppTypeFor RTNAME(Nint16_8)( +CppTypeFor RTDECL(Nint16_8)( CppTypeFor); #if defined __SIZEOF_INT128__ -CppTypeFor RTNAME(Nint16_16)( +CppTypeFor RTDECL(Nint16_16)( CppTypeFor); #endif #endif @@ -301,113 +301,113 @@ CppTypeFor RTNAME(Nint16_16)( // NEAREST // The second argument to NEAREST is the result of a comparison // to zero (i.e., S > 0) -CppTypeFor RTNAME(Nearest4)( +CppTypeFor RTDECL(Nearest4)( CppTypeFor, bool positive); -CppTypeFor RTNAME(Nearest8)( +CppTypeFor RTDECL(Nearest8)( CppTypeFor, bool positive); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Nearest10)( +CppTypeFor RTDECL(Nearest10)( CppTypeFor, bool positive); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Nearest16)( +CppTypeFor RTDECL(Nearest16)( CppTypeFor, bool positive); #endif // RRSPACING -CppTypeFor RTNAME(RRSpacing4)( +CppTypeFor RTDECL(RRSpacing4)( CppTypeFor); -CppTypeFor RTNAME(RRSpacing8)( +CppTypeFor RTDECL(RRSpacing8)( CppTypeFor); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(RRSpacing10)( +CppTypeFor RTDECL(RRSpacing10)( CppTypeFor); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(RRSpacing16)( +CppTypeFor RTDECL(RRSpacing16)( CppTypeFor); #endif // SET_EXPONENT's I= argument can be any INTEGER kind; upcast it to 64-bit -CppTypeFor RTNAME(SetExponent4)( +CppTypeFor RTDECL(SetExponent4)( CppTypeFor, std::int64_t); -CppTypeFor RTNAME(SetExponent8)( +CppTypeFor RTDECL(SetExponent8)( CppTypeFor, std::int64_t); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(SetExponent10)( +CppTypeFor RTDECL(SetExponent10)( CppTypeFor, std::int64_t); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(SetExponent16)( +CppTypeFor RTDECL(SetExponent16)( CppTypeFor, std::int64_t); #endif // SCALE -CppTypeFor RTNAME(Scale4)( +CppTypeFor RTDECL(Scale4)( CppTypeFor, std::int64_t); -CppTypeFor RTNAME(Scale8)( +CppTypeFor RTDECL(Scale8)( CppTypeFor, std::int64_t); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Scale10)( +CppTypeFor RTDECL(Scale10)( CppTypeFor, std::int64_t); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Scale16)( +CppTypeFor RTDECL(Scale16)( CppTypeFor, std::int64_t); #endif // SELECTED_INT_KIND -CppTypeFor RTNAME(SelectedIntKind)( +CppTypeFor RTDECL(SelectedIntKind)( const char *, int, void *, int); // SELECTED_REAL_KIND -CppTypeFor RTNAME(SelectedRealKind)( +CppTypeFor RTDECL(SelectedRealKind)( const char *, int, void *, int, void *, int, void *, int); // SPACING -CppTypeFor RTNAME(Spacing4)( +CppTypeFor RTDECL(Spacing4)( CppTypeFor); -CppTypeFor RTNAME(Spacing8)( +CppTypeFor RTDECL(Spacing8)( CppTypeFor); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Spacing10)( +CppTypeFor RTDECL(Spacing10)( CppTypeFor); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(Spacing16)( +CppTypeFor RTDECL(Spacing16)( CppTypeFor); #endif -CppTypeFor RTNAME(FPow4i)( +CppTypeFor RTDECL(FPow4i)( CppTypeFor b, CppTypeFor e); -CppTypeFor RTNAME(FPow8i)( +CppTypeFor RTDECL(FPow8i)( CppTypeFor b, CppTypeFor e); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(FPow10i)( +CppTypeFor RTDECL(FPow10i)( CppTypeFor b, CppTypeFor e); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(FPow16i)( +CppTypeFor RTDECL(FPow16i)( CppTypeFor b, CppTypeFor e); #endif -CppTypeFor RTNAME(FPow4k)( +CppTypeFor RTDECL(FPow4k)( CppTypeFor b, CppTypeFor e); -CppTypeFor RTNAME(FPow8k)( +CppTypeFor RTDECL(FPow8k)( CppTypeFor b, CppTypeFor e); #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(FPow10k)( +CppTypeFor RTDECL(FPow10k)( CppTypeFor b, CppTypeFor e); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(FPow16k)( +CppTypeFor RTDECL(FPow16k)( CppTypeFor b, CppTypeFor e); #endif diff --git a/flang/include/flang/Runtime/pointer.h b/flang/include/flang/Runtime/pointer.h index 52ab9482ed953f3a77eae5bab662954c694f0068..6ceb70ebb676d01d0524904b07a2acc0340e2055 100644 --- a/flang/include/flang/Runtime/pointer.h +++ b/flang/include/flang/Runtime/pointer.h @@ -21,45 +21,45 @@ extern "C" { // Data pointer initialization for NULLIFY(), "p=>NULL()`, & for ALLOCATE(). // Initializes a pointer to a disassociated state for NULLIFY() or "p=>NULL()". -void RTNAME(PointerNullifyIntrinsic)( +void RTDECL(PointerNullifyIntrinsic)( Descriptor &, TypeCategory, int kind, int rank = 0, int corank = 0); -void RTNAME(PointerNullifyCharacter)(Descriptor &, SubscriptValue length = 0, +void RTDECL(PointerNullifyCharacter)(Descriptor &, SubscriptValue length = 0, int kind = 1, int rank = 0, int corank = 0); -void RTNAME(PointerNullifyDerived)( +void RTDECL(PointerNullifyDerived)( Descriptor &, const typeInfo::DerivedType &, int rank = 0, int corank = 0); // Explicitly sets the bounds of an initialized disassociated pointer. // The upper cobound is ignored for the last codimension. -void RTNAME(PointerSetBounds)( +void RTDECL(PointerSetBounds)( Descriptor &, int zeroBasedDim, SubscriptValue lower, SubscriptValue upper); -void RTNAME(PointerSetCoBounds)(Descriptor &, int zeroBasedCoDim, +void RTDECL(PointerSetCoBounds)(Descriptor &, int zeroBasedCoDim, SubscriptValue lower, SubscriptValue upper = 0); // Length type parameters are indexed in declaration order; i.e., 0 is the // first length type parameter in the deepest base type. (Not for use // with CHARACTER; see above.) -void RTNAME(PointerSetDerivedLength)(Descriptor &, int which, SubscriptValue); +void RTDECL(PointerSetDerivedLength)(Descriptor &, int which, SubscriptValue); // For MOLD= allocation: acquires information from another descriptor // to initialize a null data pointer. -void RTNAME(PointerApplyMold)( +void RTDECL(PointerApplyMold)( Descriptor &, const Descriptor &mold, int rank = 0); // Data pointer association for "p=>TARGET" // Associates a scalar pointer with a simple scalar target. -void RTNAME(PointerAssociateScalar)(Descriptor &, void *); +void RTDECL(PointerAssociateScalar)(Descriptor &, void *); // Associates a pointer with a target of the same rank, possibly with new lower // bounds, which are passed in a vector whose length must equal the rank. -void RTNAME(PointerAssociate)(Descriptor &, const Descriptor &target); -void RTNAME(PointerAssociateLowerBounds)( +void RTDECL(PointerAssociate)(Descriptor &, const Descriptor &target); +void RTDECL(PointerAssociateLowerBounds)( Descriptor &, const Descriptor &target, const Descriptor &lowerBounds); // Associates a pointer with a target with bounds remapping. The target must be // simply contiguous &/or of rank 1. The bounds constitute a [2,newRank] // integer array whose columns are [lower bound, upper bound] on each dimension. -void RTNAME(PointerAssociateRemapping)(Descriptor &, const Descriptor &target, +void RTDECL(PointerAssociateRemapping)(Descriptor &, const Descriptor &target, const Descriptor &bounds, const char *sourceFile = nullptr, int sourceLine = 0); @@ -70,7 +70,7 @@ void RTNAME(PointerAssociateRemapping)(Descriptor &, const Descriptor &target, // a derived type or CHARACTER value, the explicit value has to match // the length type parameter's value. This API checks that requirement. // Returns 0 for success, or the STAT= value on failure with hasStat==true. -int RTNAME(PointerCheckLengthParameter)(Descriptor &, +int RTDECL(PointerCheckLengthParameter)(Descriptor &, int which /* 0 for CHARACTER length */, SubscriptValue other, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); @@ -83,10 +83,10 @@ int RTNAME(PointerCheckLengthParameter)(Descriptor &, // Successfully allocated memory is initialized if the pointer has a // derived type, and is always initialized by PointerAllocateSource(). // Performs all necessary coarray synchronization and validation actions. -int RTNAME(PointerAllocate)(Descriptor &, bool hasStat = false, +int RTDECL(PointerAllocate)(Descriptor &, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); -int RTNAME(PointerAllocateSource)(Descriptor &, const Descriptor &source, +int RTDECL(PointerAllocateSource)(Descriptor &, const Descriptor &source, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); @@ -95,13 +95,13 @@ int RTNAME(PointerAllocateSource)(Descriptor &, const Descriptor &source, // Finalizes elements &/or components as needed. The pointer is left // in an initialized disassociated state suitable for reallocation // with the same bounds, cobounds, and length type parameters. -int RTNAME(PointerDeallocate)(Descriptor &, bool hasStat = false, +int RTDECL(PointerDeallocate)(Descriptor &, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); // Same as PointerDeallocate but also set the dynamic type as the declared type // as mentioned in 7.3.2.3 note 7. -int RTNAME(PointerDeallocatePolymorphic)(Descriptor &, +int RTDECL(PointerDeallocatePolymorphic)(Descriptor &, const typeInfo::DerivedType *, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); @@ -109,10 +109,10 @@ int RTNAME(PointerDeallocatePolymorphic)(Descriptor &, // Association inquiries for ASSOCIATED() // True when the pointer is not disassociated. -bool RTNAME(PointerIsAssociated)(const Descriptor &); +bool RTDECL(PointerIsAssociated)(const Descriptor &); // True when the pointer is associated with a specific target. -bool RTNAME(PointerIsAssociatedWith)( +bool RTDECL(PointerIsAssociatedWith)( const Descriptor &, const Descriptor *target); } // extern "C" diff --git a/flang/include/flang/Runtime/ragged.h b/flang/include/flang/Runtime/ragged.h index e4b5838212a845e0a674ea3f8064c3fe7211eefc..f52a619c55b43e838540a1e2c05acbb9ac2da9f0 100644 --- a/flang/include/flang/Runtime/ragged.h +++ b/flang/include/flang/Runtime/ragged.h @@ -29,11 +29,6 @@ struct RaggedArrayHeader { std::int64_t *extentPointer; }; -RaggedArrayHeader *RaggedArrayAllocate( - RaggedArrayHeader *, bool, std::int64_t, std::int64_t, std::int64_t *); - -void RaggedArrayDeallocate(RaggedArrayHeader *); - extern "C" { // For more on ragged arrays see https://en.wikipedia.org/wiki/Jagged_array. The @@ -53,12 +48,12 @@ extern "C" { // non-negative rank indicates the length of the extentVector, which is a list // of non-negative extents. elementSize is the size of a data element in the // rectangular space defined by the extentVector. -void *RTNAME(RaggedArrayAllocate)(void *header, bool isHeader, +void *RTDECL(RaggedArrayAllocate)(void *header, bool isHeader, std::int64_t rank, std::int64_t elementSize, std::int64_t *extentVector); // Runtime helper for deallocation of ragged array buffers. The root header of // the ragged array structure is passed to deallocate the entire ragged array. -void RTNAME(RaggedArrayDeallocate)(void *raggedArrayHeader); +void RTDECL(RaggedArrayDeallocate)(void *raggedArrayHeader); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Runtime/reduction.h b/flang/include/flang/Runtime/reduction.h index a8469cb9dac872b202d7af9841fd723f295ffb56..b91fec0cd26b51c38266c33c8372ec277d494ed7 100644 --- a/flang/include/flang/Runtime/reduction.h +++ b/flang/include/flang/Runtime/reduction.h @@ -46,389 +46,389 @@ extern "C" { // SUM() -std::int8_t RTNAME(SumInteger1)(const Descriptor &, const char *source, +std::int8_t RTDECL(SumInteger1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(SumInteger2)(const Descriptor &, const char *source, +std::int16_t RTDECL(SumInteger2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(SumInteger4)(const Descriptor &, const char *source, +std::int32_t RTDECL(SumInteger4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(SumInteger8)(const Descriptor &, const char *source, +std::int64_t RTDECL(SumInteger8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(SumInteger16)(const Descriptor &, const char *source, +common::int128_t RTDECL(SumInteger16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif // REAL/COMPLEX(2 & 3) return 32-bit float results for the caller to downconvert -float RTNAME(SumReal2)(const Descriptor &, const char *source, int line, +float RTDECL(SumReal2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(SumReal3)(const Descriptor &, const char *source, int line, +float RTDECL(SumReal3)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(SumReal4)(const Descriptor &, const char *source, int line, +float RTDECL(SumReal4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -double RTNAME(SumReal8)(const Descriptor &, const char *source, int line, +double RTDECL(SumReal8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #if LDBL_MANT_DIG == 64 -long double RTNAME(SumReal10)(const Descriptor &, const char *source, int line, +long double RTDECL(SumReal10)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppFloat128Type RTNAME(SumReal16)(const Descriptor &, const char *source, +CppFloat128Type RTDECL(SumReal16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(CppSumComplex2)(std::complex &, const Descriptor &, +void RTDECL(CppSumComplex2)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppSumComplex3)(std::complex &, const Descriptor &, +void RTDECL(CppSumComplex3)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppSumComplex4)(std::complex &, const Descriptor &, +void RTDECL(CppSumComplex4)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppSumComplex8)(std::complex &, const Descriptor &, +void RTDECL(CppSumComplex8)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppSumComplex10)(std::complex &, const Descriptor &, +void RTDECL(CppSumComplex10)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppSumComplex16)(std::complex &, const Descriptor &, +void RTDECL(CppSumComplex16)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(SumDim)(Descriptor &result, const Descriptor &array, int dim, +void RTDECL(SumDim)(Descriptor &result, const Descriptor &array, int dim, const char *source, int line, const Descriptor *mask = nullptr); // PRODUCT() -std::int8_t RTNAME(ProductInteger1)(const Descriptor &, const char *source, +std::int8_t RTDECL(ProductInteger1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(ProductInteger2)(const Descriptor &, const char *source, +std::int16_t RTDECL(ProductInteger2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(ProductInteger4)(const Descriptor &, const char *source, +std::int32_t RTDECL(ProductInteger4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(ProductInteger8)(const Descriptor &, const char *source, +std::int64_t RTDECL(ProductInteger8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(ProductInteger16)(const Descriptor &, +common::int128_t RTDECL(ProductInteger16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif // REAL/COMPLEX(2 & 3) return 32-bit float results for the caller to downconvert -float RTNAME(ProductReal2)(const Descriptor &, const char *source, int line, +float RTDECL(ProductReal2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(ProductReal3)(const Descriptor &, const char *source, int line, +float RTDECL(ProductReal3)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(ProductReal4)(const Descriptor &, const char *source, int line, +float RTDECL(ProductReal4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -double RTNAME(ProductReal8)(const Descriptor &, const char *source, int line, +double RTDECL(ProductReal8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #if LDBL_MANT_DIG == 64 -long double RTNAME(ProductReal10)(const Descriptor &, const char *source, +long double RTDECL(ProductReal10)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppFloat128Type RTNAME(ProductReal16)(const Descriptor &, const char *source, +CppFloat128Type RTDECL(ProductReal16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(CppProductComplex2)(std::complex &, const Descriptor &, +void RTDECL(CppProductComplex2)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppProductComplex3)(std::complex &, const Descriptor &, +void RTDECL(CppProductComplex3)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppProductComplex4)(std::complex &, const Descriptor &, +void RTDECL(CppProductComplex4)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppProductComplex8)(std::complex &, const Descriptor &, +void RTDECL(CppProductComplex8)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppProductComplex10)(std::complex &, +void RTDECL(CppProductComplex10)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(CppProductComplex16)(std::complex &, +void RTDECL(CppProductComplex16)(std::complex &, const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -void RTNAME(ProductDim)(Descriptor &result, const Descriptor &array, int dim, +void RTDECL(ProductDim)(Descriptor &result, const Descriptor &array, int dim, const char *source, int line, const Descriptor *mask = nullptr); // IALL, IANY, IPARITY -std::int8_t RTNAME(IAll1)(const Descriptor &, const char *source, int line, +std::int8_t RTDECL(IAll1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(IAll2)(const Descriptor &, const char *source, int line, +std::int16_t RTDECL(IAll2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(IAll4)(const Descriptor &, const char *source, int line, +std::int32_t RTDECL(IAll4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(IAll8)(const Descriptor &, const char *source, int line, +std::int64_t RTDECL(IAll8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(IAll16)(const Descriptor &, const char *source, +common::int128_t RTDECL(IAll16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(IAllDim)(Descriptor &result, const Descriptor &array, int dim, +void RTDECL(IAllDim)(Descriptor &result, const Descriptor &array, int dim, const char *source, int line, const Descriptor *mask = nullptr); -std::int8_t RTNAME(IAny1)(const Descriptor &, const char *source, int line, +std::int8_t RTDECL(IAny1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(IAny2)(const Descriptor &, const char *source, int line, +std::int16_t RTDECL(IAny2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(IAny4)(const Descriptor &, const char *source, int line, +std::int32_t RTDECL(IAny4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(IAny8)(const Descriptor &, const char *source, int line, +std::int64_t RTDECL(IAny8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(IAny16)(const Descriptor &, const char *source, +common::int128_t RTDECL(IAny16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(IAnyDim)(Descriptor &result, const Descriptor &array, int dim, +void RTDECL(IAnyDim)(Descriptor &result, const Descriptor &array, int dim, const char *source, int line, const Descriptor *mask = nullptr); -std::int8_t RTNAME(IParity1)(const Descriptor &, const char *source, int line, +std::int8_t RTDECL(IParity1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(IParity2)(const Descriptor &, const char *source, int line, +std::int16_t RTDECL(IParity2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(IParity4)(const Descriptor &, const char *source, int line, +std::int32_t RTDECL(IParity4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(IParity8)(const Descriptor &, const char *source, int line, +std::int64_t RTDECL(IParity8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(IParity16)(const Descriptor &, const char *source, +common::int128_t RTDECL(IParity16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(IParityDim)(Descriptor &result, const Descriptor &array, int dim, +void RTDECL(IParityDim)(Descriptor &result, const Descriptor &array, int dim, const char *source, int line, const Descriptor *mask = nullptr); // FINDLOC, MAXLOC, & MINLOC // These return allocated arrays in the supplied descriptor. // The default value for KIND= should be the default INTEGER in effect at // compilation time. -void RTNAME(Findloc)(Descriptor &, const Descriptor &x, +void RTDECL(Findloc)(Descriptor &, const Descriptor &x, const Descriptor &target, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(FindlocDim)(Descriptor &, const Descriptor &x, +void RTDECL(FindlocDim)(Descriptor &, const Descriptor &x, const Descriptor &target, int kind, int dim, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocCharacter)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocCharacter)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocInteger1)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocInteger1)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocInteger2)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocInteger2)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocInteger4)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocInteger4)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocInteger8)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocInteger8)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocInteger16)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocInteger16)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocReal4)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocReal4)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocReal8)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocReal8)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocReal10)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocReal10)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocReal16)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MaxlocReal16)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MaxlocDim)(Descriptor &, const Descriptor &x, int kind, int dim, +void RTDECL(MaxlocDim)(Descriptor &, const Descriptor &x, int kind, int dim, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocCharacter)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocCharacter)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocInteger1)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocInteger1)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocInteger2)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocInteger2)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocInteger4)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocInteger4)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocInteger8)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocInteger8)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocInteger16)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocInteger16)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocReal4)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocReal4)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocReal8)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocReal8)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocReal10)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocReal10)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocReal16)(Descriptor &, const Descriptor &, int kind, +void RTDECL(MinlocReal16)(Descriptor &, const Descriptor &, int kind, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); -void RTNAME(MinlocDim)(Descriptor &, const Descriptor &x, int kind, int dim, +void RTDECL(MinlocDim)(Descriptor &, const Descriptor &x, int kind, int dim, const char *source, int line, const Descriptor *mask = nullptr, bool back = false); // MAXVAL and MINVAL -std::int8_t RTNAME(MaxvalInteger1)(const Descriptor &, const char *source, +std::int8_t RTDECL(MaxvalInteger1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(MaxvalInteger2)(const Descriptor &, const char *source, +std::int16_t RTDECL(MaxvalInteger2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(MaxvalInteger4)(const Descriptor &, const char *source, +std::int32_t RTDECL(MaxvalInteger4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(MaxvalInteger8)(const Descriptor &, const char *source, +std::int64_t RTDECL(MaxvalInteger8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(MaxvalInteger16)(const Descriptor &, const char *source, +common::int128_t RTDECL(MaxvalInteger16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -float RTNAME(MaxvalReal2)(const Descriptor &, const char *source, int line, +float RTDECL(MaxvalReal2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(MaxvalReal3)(const Descriptor &, const char *source, int line, +float RTDECL(MaxvalReal3)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(MaxvalReal4)(const Descriptor &, const char *source, int line, +float RTDECL(MaxvalReal4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -double RTNAME(MaxvalReal8)(const Descriptor &, const char *source, int line, +double RTDECL(MaxvalReal8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #if LDBL_MANT_DIG == 64 -long double RTNAME(MaxvalReal10)(const Descriptor &, const char *source, +long double RTDECL(MaxvalReal10)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppFloat128Type RTNAME(MaxvalReal16)(const Descriptor &, const char *source, +CppFloat128Type RTDECL(MaxvalReal16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(MaxvalCharacter)(Descriptor &, const Descriptor &, +void RTDECL(MaxvalCharacter)(Descriptor &, const Descriptor &, const char *source, int line, const Descriptor *mask = nullptr); -std::int8_t RTNAME(MinvalInteger1)(const Descriptor &, const char *source, +std::int8_t RTDECL(MinvalInteger1)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int16_t RTNAME(MinvalInteger2)(const Descriptor &, const char *source, +std::int16_t RTDECL(MinvalInteger2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int32_t RTNAME(MinvalInteger4)(const Descriptor &, const char *source, +std::int32_t RTDECL(MinvalInteger4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -std::int64_t RTNAME(MinvalInteger8)(const Descriptor &, const char *source, +std::int64_t RTDECL(MinvalInteger8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(MinvalInteger16)(const Descriptor &, const char *source, +common::int128_t RTDECL(MinvalInteger16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -float RTNAME(MinvalReal2)(const Descriptor &, const char *source, int line, +float RTDECL(MinvalReal2)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(MinvalReal3)(const Descriptor &, const char *source, int line, +float RTDECL(MinvalReal3)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -float RTNAME(MinvalReal4)(const Descriptor &, const char *source, int line, +float RTDECL(MinvalReal4)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); -double RTNAME(MinvalReal8)(const Descriptor &, const char *source, int line, +double RTDECL(MinvalReal8)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #if LDBL_MANT_DIG == 64 -long double RTNAME(MinvalReal10)(const Descriptor &, const char *source, +long double RTDECL(MinvalReal10)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppFloat128Type RTNAME(MinvalReal16)(const Descriptor &, const char *source, +CppFloat128Type RTDECL(MinvalReal16)(const Descriptor &, const char *source, int line, int dim = 0, const Descriptor *mask = nullptr); #endif -void RTNAME(MinvalCharacter)(Descriptor &, const Descriptor &, +void RTDECL(MinvalCharacter)(Descriptor &, const Descriptor &, const char *source, int line, const Descriptor *mask = nullptr); -void RTNAME(MaxvalDim)(Descriptor &, const Descriptor &, int dim, +void RTDECL(MaxvalDim)(Descriptor &, const Descriptor &, int dim, const char *source, int line, const Descriptor *mask = nullptr); -void RTNAME(MinvalDim)(Descriptor &, const Descriptor &, int dim, +void RTDECL(MinvalDim)(Descriptor &, const Descriptor &, int dim, const char *source, int line, const Descriptor *mask = nullptr); // NORM2 -float RTNAME(Norm2_2)( +float RTDECL(Norm2_2)( const Descriptor &, const char *source, int line, int dim = 0); -float RTNAME(Norm2_3)( +float RTDECL(Norm2_3)( const Descriptor &, const char *source, int line, int dim = 0); -float RTNAME(Norm2_4)( +float RTDECL(Norm2_4)( const Descriptor &, const char *source, int line, int dim = 0); -double RTNAME(Norm2_8)( +double RTDECL(Norm2_8)( const Descriptor &, const char *source, int line, int dim = 0); #if LDBL_MANT_DIG == 64 -long double RTNAME(Norm2_10)( +long double RTDECL(Norm2_10)( const Descriptor &, const char *source, int line, int dim = 0); #elif LDBL_MANT_DIG == 113 -long double RTNAME(Norm2_16)( +long double RTDECL(Norm2_16)( const Descriptor &, const char *source, int line, int dim = 0); #endif -void RTNAME(Norm2Dim)( +void RTDECL(Norm2Dim)( Descriptor &, const Descriptor &, int dim, const char *source, int line); // ALL, ANY, COUNT, & PARITY logical reductions -bool RTNAME(All)(const Descriptor &, const char *source, int line, int dim = 0); -void RTNAME(AllDim)(Descriptor &result, const Descriptor &, int dim, +bool RTDECL(All)(const Descriptor &, const char *source, int line, int dim = 0); +void RTDECL(AllDim)(Descriptor &result, const Descriptor &, int dim, const char *source, int line); -bool RTNAME(Any)(const Descriptor &, const char *source, int line, int dim = 0); -void RTNAME(AnyDim)(Descriptor &result, const Descriptor &, int dim, +bool RTDECL(Any)(const Descriptor &, const char *source, int line, int dim = 0); +void RTDECL(AnyDim)(Descriptor &result, const Descriptor &, int dim, const char *source, int line); -std::int64_t RTNAME(Count)( +std::int64_t RTDECL(Count)( const Descriptor &, const char *source, int line, int dim = 0); -void RTNAME(CountDim)(Descriptor &result, const Descriptor &, int dim, int kind, +void RTDECL(CountDim)(Descriptor &result, const Descriptor &, int dim, int kind, const char *source, int line); -bool RTNAME(Parity)( +bool RTDECL(Parity)( const Descriptor &, const char *source, int line, int dim = 0); -void RTNAME(ParityDim)(Descriptor &result, const Descriptor &, int dim, +void RTDECL(ParityDim)(Descriptor &result, const Descriptor &, int dim, const char *source, int line); // DOT_PRODUCT -std::int8_t RTNAME(DotProductInteger1)(const Descriptor &, const Descriptor &, +std::int8_t RTDECL(DotProductInteger1)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -std::int16_t RTNAME(DotProductInteger2)(const Descriptor &, const Descriptor &, +std::int16_t RTDECL(DotProductInteger2)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -std::int32_t RTNAME(DotProductInteger4)(const Descriptor &, const Descriptor &, +std::int32_t RTDECL(DotProductInteger4)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -std::int64_t RTNAME(DotProductInteger8)(const Descriptor &, const Descriptor &, +std::int64_t RTDECL(DotProductInteger8)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #ifdef __SIZEOF_INT128__ -common::int128_t RTNAME(DotProductInteger16)(const Descriptor &, +common::int128_t RTDECL(DotProductInteger16)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #endif -float RTNAME(DotProductReal2)(const Descriptor &, const Descriptor &, +float RTDECL(DotProductReal2)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -float RTNAME(DotProductReal3)(const Descriptor &, const Descriptor &, +float RTDECL(DotProductReal3)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -float RTNAME(DotProductReal4)(const Descriptor &, const Descriptor &, +float RTDECL(DotProductReal4)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -double RTNAME(DotProductReal8)(const Descriptor &, const Descriptor &, +double RTDECL(DotProductReal8)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #if LDBL_MANT_DIG == 64 -long double RTNAME(DotProductReal10)(const Descriptor &, const Descriptor &, +long double RTDECL(DotProductReal10)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppFloat128Type RTNAME(DotProductReal16)(const Descriptor &, const Descriptor &, +CppFloat128Type RTDECL(DotProductReal16)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #endif -void RTNAME(CppDotProductComplex2)(std::complex &, const Descriptor &, +void RTDECL(CppDotProductComplex2)(std::complex &, const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -void RTNAME(CppDotProductComplex3)(std::complex &, const Descriptor &, +void RTDECL(CppDotProductComplex3)(std::complex &, const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -void RTNAME(CppDotProductComplex4)(std::complex &, const Descriptor &, +void RTDECL(CppDotProductComplex4)(std::complex &, const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); -void RTNAME(CppDotProductComplex8)(std::complex &, const Descriptor &, +void RTDECL(CppDotProductComplex8)(std::complex &, const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #if LDBL_MANT_DIG == 64 -void RTNAME(CppDotProductComplex10)(std::complex &, +void RTDECL(CppDotProductComplex10)(std::complex &, const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -void RTNAME(CppDotProductComplex16)(std::complex &, +void RTDECL(CppDotProductComplex16)(std::complex &, const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); #endif -bool RTNAME(DotProductLogical)(const Descriptor &, const Descriptor &, +bool RTDECL(DotProductLogical)(const Descriptor &, const Descriptor &, const char *source = nullptr, int line = 0); } // extern "C" diff --git a/flang/include/flang/Runtime/support.h b/flang/include/flang/Runtime/support.h index 1262a04b5cd4fc4c4752dc452748a30fb26cc646..e7ae2154b2a72b187acede2f0e3ed400930ce450 100644 --- a/flang/include/flang/Runtime/support.h +++ b/flang/include/flang/Runtime/support.h @@ -21,7 +21,7 @@ class Descriptor; extern "C" { // Predicate: is the storage described by a Descriptor contiguous in memory? -bool RTNAME(IsContiguous)(const Descriptor &); +bool RTDECL(IsContiguous)(const Descriptor &); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index d3e4dc6cd4a243e817a05af72d2d2a0a6aadd032..96d3869cd093912c3f14b38f89540c7e58ca068a 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -10,6 +10,7 @@ /// debugging the test tools. This file must be included into the tool. #include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Pass/PassManager.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" @@ -311,6 +312,20 @@ inline void createDefaultFIRCodeGenPassPipeline( if (config.VScaleMin != 0) pm.addPass(fir::createVScaleAttrPass({config.VScaleMin, config.VScaleMax})); + // Add function attributes + fir::FunctionAttrTypes functionAttrs; + + if (config.FramePointerKind != llvm::FramePointerKind::None) { + if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf) + functionAttrs.framePointerKind = + mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; + else + functionAttrs.framePointerKind = + mlir::LLVM::framePointerKind::FramePointerKind::All; + + pm.addPass(fir::createFunctionAttrPass(functionAttrs)); + } + fir::addFIRToLLVMPass(pm, config); } diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index ddec70fa9824c52fe654b67dc4d302c5112f8951..b346b30b158aecca636e835150e405e2fda50992 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -35,6 +35,7 @@ struct MLIRToLLVMPassPipelineConfig { LoopVersioning = opts.LoopVersioning; DebugInfo = opts.getDebugInfo(); AliasAnalysis = opts.AliasAnalysis; + FramePointerKind = opts.getFramePointer(); } llvm::OptimizationLevel OptLevel; ///< optimisation level @@ -44,6 +45,8 @@ struct MLIRToLLVMPassPipelineConfig { bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR llvm::codegenoptions::DebugInfoKind DebugInfo = llvm::codegenoptions::NoDebugInfo; ///< Debug info generation. + llvm::FramePointerKind FramePointerKind = + llvm::FramePointerKind::None; ///< Add frame pointer to functions. unsigned VScaleMin = 0; ///< SVE vector range minimum. unsigned VScaleMax = 0; ///< SVE vector range maximum. }; diff --git a/flang/lib/Decimal/big-radix-floating-point.h b/flang/lib/Decimal/big-radix-floating-point.h index 7d5d31b7788d761e0aa9121173b06a2e495f4328..2143d1d9b3f7763553007d7ec97eea7c9f0b5848 100644 --- a/flang/lib/Decimal/big-radix-floating-point.h +++ b/flang/lib/Decimal/big-radix-floating-point.h @@ -369,6 +369,12 @@ private: } return result; } + constexpr Raw HUGE() const { + Raw result{static_cast(Real::maxExponent)}; + result <<= Real::significandBits; + result |= SignBit(); + return result - 1; // decrement exponent, set all significand bits + } Digit digit_[maxDigits]; // in little-endian order: digit_[0] is LSD int digits_{0}; // # of elements in digit_[] array; zero when zero diff --git a/flang/lib/Decimal/decimal-to-binary.cpp b/flang/lib/Decimal/decimal-to-binary.cpp index d5b66b9fb9338886282689b24744188c90bfa943..d38af0f9b800504f07d6e76471c7503a04949455 100644 --- a/flang/lib/Decimal/decimal-to-binary.cpp +++ b/flang/lib/Decimal/decimal-to-binary.cpp @@ -237,6 +237,15 @@ private: int exponent_{0}; }; +// The standard says that these overflow cases round to "representable" +// numbers, and some popular compilers interpret that to mean +/-HUGE() +// rather than +/-Inf. +static inline constexpr bool RoundOverflowToHuge( + enum FortranRounding rounding, bool isNegative) { + return rounding == RoundToZero || (!isNegative && rounding == RoundDown) || + (isNegative && rounding == RoundUp); +} + template ConversionToBinaryResult IntermediateFloat::ToBinary( bool isNegative, FortranRounding rounding) const { @@ -256,12 +265,18 @@ ConversionToBinaryResult IntermediateFloat::ToBinary( if (guard != 0) { flags |= Inexact; } - if (fraction == 0 && guard <= oneHalf) { - if ((!isNegative && rounding == RoundUp) || - (isNegative && rounding == RoundDown)) { - // round to minimum nonzero value - } else { - return {Binary{}, static_cast(flags)}; + if (fraction == 0) { + if (guard <= oneHalf) { + if ((!isNegative && rounding == RoundUp) || + (isNegative && rounding == RoundDown)) { + // round to least nonzero value + expo = 0; + } else { // round to zero + if (guard != 0) { + flags |= Underflow; + } + return {Binary{}, static_cast(flags)}; + } } } else { // The value is nonzero; normalize it. @@ -301,14 +316,21 @@ ConversionToBinaryResult IntermediateFloat::ToBinary( } if (expo == 1 && fraction < topBit) { expo = 0; // subnormal - } - if (expo >= Binary::maxExponent) { - expo = Binary::maxExponent; // Inf - flags |= Overflow; - if constexpr (Binary::bits == 80) { // x87 - fraction = IntType{1} << 63; - } else { - fraction = 0; + flags |= Underflow; + } else if (expo == 0) { + flags |= Underflow; + } else if (expo >= Binary::maxExponent) { + if (RoundOverflowToHuge(rounding, isNegative)) { + expo = Binary::maxExponent - 1; + fraction = mask; + } else { // Inf + expo = Binary::maxExponent; + flags |= Overflow; + if constexpr (Binary::bits == 80) { // x87 + fraction = IntType{1} << 63; + } else { + fraction = 0; + } } } using Raw = typename Binary::RawType; @@ -338,14 +360,22 @@ BigRadixFloatingPointNumber::ConvertToBinary() { // Sanity checks for ridiculous exponents static constexpr int crazy{2 * Real::decimalRange + log10Radix}; if (exponent_ < -crazy) { + enum ConversionResultFlags flags { + static_cast(Inexact | Underflow) + }; if ((!isNegative_ && rounding_ == RoundUp) || (isNegative_ && rounding_ == RoundDown)) { - return {Real{Raw{1} | SignBit()}}; // return least nonzero value + // return least nonzero value + return {Real{Raw{1} | SignBit()}, flags}; } else { // underflow to +/-0. - return {Real{SignBit()}, Inexact}; + return {Real{SignBit()}, flags}; + } + } else if (exponent_ > crazy) { // overflow to +/-HUGE() or +/-Inf + if (RoundOverflowToHuge(rounding_, isNegative_)) { + return {Real{HUGE()}}; + } else { + return {Real{Infinity()}, Overflow}; } - } else if (exponent_ > crazy) { // overflow to +/-Inf. - return {Real{Infinity()}, Overflow}; } // Apply any negative decimal exponent by multiplication // by a power of two, adjusting the binary exponent to compensate. diff --git a/flang/lib/Evaluate/real.cpp b/flang/lib/Evaluate/real.cpp index 4fecaa1a131f81ddf3513bb457de6ff2781c1e5c..cb8be98bb6f40fc5869f06b9bed4af13364e8875 100644 --- a/flang/lib/Evaluate/real.cpp +++ b/flang/lib/Evaluate/real.cpp @@ -350,7 +350,7 @@ ValueWithRealFlags> Real::NEAREST(bool upward) const { isNegative = !isNegative; } else { auto sub1{fraction.SubtractSigned(one)}; - if (sub1.overflow) { + if (sub1.overflow && expo > 1) { nearest = Fraction{0}.NOT(); --expo; } else { diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 8c755da4a2d8b81ef14ecdf20e402b7d35d0c41f..7834364bccc40067e36d3952192f9fc2eb7393ee 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1724,9 +1724,13 @@ bool IsLenTypeParameter(const Symbol &symbol) { } bool IsExtensibleType(const DerivedTypeSpec *derived) { - return derived && !IsIsoCType(derived) && - !derived->typeSymbol().attrs().test(Attr::BIND_C) && - !derived->typeSymbol().get().sequence(); + return !IsSequenceOrBindCType(derived) && !IsIsoCType(derived); +} + +bool IsSequenceOrBindCType(const DerivedTypeSpec *derived) { + return derived && + (derived->typeSymbol().attrs().test(Attr::BIND_C) || + derived->typeSymbol().get().sequence()); } bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name) { @@ -1761,6 +1765,10 @@ bool IsLockType(const DerivedTypeSpec *derived) { return IsBuiltinDerivedType(derived, "lock_type"); } +bool IsNotifyType(const DerivedTypeSpec *derived) { + return IsBuiltinDerivedType(derived, "notify_type"); +} + bool IsTeamType(const DerivedTypeSpec *derived) { return IsBuiltinDerivedType(derived, "team_type"); } diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp index a6b8f1a9d29ee4746ebf67c39bb3d4f154178b1f..555ac91f6dc7c077cdfec74390b0b4e631a9ef6c 100644 --- a/flang/lib/Frontend/CompilerInstance.cpp +++ b/flang/lib/Frontend/CompilerInstance.cpp @@ -257,7 +257,7 @@ getExplicitAndImplicitNVPTXTargetFeatures(clang::DiagnosticsEngine &diags, llvm::StringRef userKeyString(llvm::StringRef(userFeature).drop_front(1)); implicitFeaturesMap[userKeyString.str()] = (userFeature[0] == '+'); // Check if the user provided a PTX version - if (userKeyString.startswith("ptx")) + if (userKeyString.starts_with("ptx")) ptxVer = true; } diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index b3f32bb241d06808ff09a6b49f279fc4afcc5168..b65b6e31bea82144fb06af8e80bec09d7b236329 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -245,6 +245,23 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.AliasAnalysis = opts.OptimizationLevel > 0; + // -mframe-pointer=none/non-leaf/all option. + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { + std::optional val = + llvm::StringSwitch>(a->getValue()) + .Case("none", llvm::FramePointerKind::None) + .Case("non-leaf", llvm::FramePointerKind::NonLeaf) + .Case("all", llvm::FramePointerKind::All) + .Default(std::nullopt); + + if (!val.has_value()) { + diags.Report(clang::diag::err_drv_invalid_value) + << a->getAsString(args) << a->getValue(); + } else + opts.setFramePointer(val.value()); + } + for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) opts.LLVMPassPlugins.push_back(a->getValue()); @@ -1085,7 +1102,7 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc, } bool CompilerInvocation::createFromArgs( - CompilerInvocation &res, llvm::ArrayRef commandLineArgs, + CompilerInvocation &invoc, llvm::ArrayRef commandLineArgs, clang::DiagnosticsEngine &diags, const char *argv0) { bool success = true; @@ -1096,7 +1113,7 @@ bool CompilerInvocation::createFromArgs( // NOTE: Like in Clang, it would be nice to use option marshalling // for this so that the entire logic for setting-up the triple is in one // place. - res.getTargetOpts().triple = + invoc.getTargetOpts().triple = llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); // Parse the arguments @@ -1128,7 +1145,7 @@ bool CompilerInvocation::createFromArgs( // -flang-experimental-hlfir if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir) || args.hasArg(clang::driver::options::OPT_emit_hlfir)) { - res.loweringOpts.setLowerToHighLevelFIR(true); + invoc.loweringOpts.setLowerToHighLevelFIR(true); } // -flang-deprecated-no-hlfir @@ -1141,16 +1158,17 @@ bool CompilerInvocation::createFromArgs( "'-flang-deprecated-no-hlfir' cannot be both specified"); diags.Report(diagID); } - res.loweringOpts.setLowerToHighLevelFIR(false); + invoc.loweringOpts.setLowerToHighLevelFIR(false); } - if (args.hasArg(clang::driver::options::OPT_flang_experimental_polymorphism)) { - res.loweringOpts.setPolymorphicTypeImpl(true); + if (args.hasArg( + clang::driver::options::OPT_flang_experimental_polymorphism)) { + invoc.loweringOpts.setPolymorphicTypeImpl(true); } // -fno-ppc-native-vector-element-order if (args.hasArg(clang::driver::options::OPT_fno_ppc_native_vec_elem_order)) { - res.loweringOpts.setNoPPCNativeVecElemOrder(true); + invoc.loweringOpts.setNoPPCNativeVecElemOrder(true); } // Preserve all the remark options requested, i.e. -Rpass, -Rpass-missed or @@ -1161,46 +1179,46 @@ bool CompilerInvocation::createFromArgs( // This is -Rfoo=, where foo is the name of the diagnostic // group. Add only the remark option name to the diagnostics. e.g. for // -Rpass= we will add the string "pass". - res.getDiagnosticOpts().Remarks.push_back( + invoc.getDiagnosticOpts().Remarks.push_back( std::string(a->getOption().getName().drop_front(1).rtrim("=-"))); else // If no regex was provided, add the provided value, e.g. for -Rpass add // the string "pass". - res.getDiagnosticOpts().Remarks.push_back(a->getValue()); + invoc.getDiagnosticOpts().Remarks.push_back(a->getValue()); } - success &= parseFrontendArgs(res.getFrontendOpts(), args, diags); - parseTargetArgs(res.getTargetOpts(), args); - parsePreprocessorArgs(res.getPreprocessorOpts(), args); - parseCodeGenArgs(res.getCodeGenOpts(), args, diags); - success &= parseDebugArgs(res.getCodeGenOpts(), args, diags); - success &= parseVectorLibArg(res.getCodeGenOpts(), args, diags); - success &= parseSemaArgs(res, args, diags); - success &= parseDialectArgs(res, args, diags); - success &= parseDiagArgs(res, args, diags); + success &= parseFrontendArgs(invoc.getFrontendOpts(), args, diags); + parseTargetArgs(invoc.getTargetOpts(), args); + parsePreprocessorArgs(invoc.getPreprocessorOpts(), args); + parseCodeGenArgs(invoc.getCodeGenOpts(), args, diags); + success &= parseDebugArgs(invoc.getCodeGenOpts(), args, diags); + success &= parseVectorLibArg(invoc.getCodeGenOpts(), args, diags); + success &= parseSemaArgs(invoc, args, diags); + success &= parseDialectArgs(invoc, args, diags); + success &= parseDiagArgs(invoc, args, diags); // Collect LLVM (-mllvm) and MLIR (-mmlir) options. // NOTE: Try to avoid adding any options directly to `llvmArgs` or // `mlirArgs`. Instead, you can use // * `-mllvm `, or // * `-mmlir `. - res.frontendOpts.llvmArgs = + invoc.frontendOpts.llvmArgs = args.getAllArgValues(clang::driver::options::OPT_mllvm); - res.frontendOpts.mlirArgs = + invoc.frontendOpts.mlirArgs = args.getAllArgValues(clang::driver::options::OPT_mmlir); - success &= parseFloatingPointArgs(res, args, diags); + success &= parseFloatingPointArgs(invoc, args, diags); - success &= parseVScaleArgs(res, args, diags); + success &= parseVScaleArgs(invoc, args, diags); - success &= parseLinkerOptionsArgs(res, args, diags); + success &= parseLinkerOptionsArgs(invoc, args, diags); // Set the string to be used as the return value of the COMPILER_OPTIONS // intrinsic of iso_fortran_env. This is either passed in from the parent // compiler driver invocation with an environment variable, or failing that // set to the command line arguments of the frontend driver invocation. - res.allCompilerInvocOpts = std::string(); - llvm::raw_string_ostream os(res.allCompilerInvocOpts); + invoc.allCompilerInvocOpts = std::string(); + llvm::raw_string_ostream os(invoc.allCompilerInvocOpts); char *compilerOptsEnv = std::getenv("FLANG_COMPILER_OPTIONS_STRING"); if (compilerOptsEnv != nullptr) { os << compilerOptsEnv; @@ -1212,7 +1230,7 @@ bool CompilerInvocation::createFromArgs( } } - res.setArgv0(argv0); + invoc.setArgv0(argv0); return success; } diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index bc09dec17b7ae341285d0278dcffc19be1ae8786..4cad640562c619067002a9a6bcff3057b5873613 100644 --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -131,7 +131,7 @@ updateDiagEngineForOptRemarks(clang::DiagnosticsEngine &diagsEng, // Check to see if this opt starts with "no-", if so, this is a // negative form of the option. - bool isPositive = !remarkOpt.startswith("no-"); + bool isPositive = !remarkOpt.starts_with("no-"); if (!isPositive) remarkOpt = remarkOpt.substr(3); diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 7e64adc3c144c9647510220c746315b91d93ad32..2bceee09b4f0f252e365e580976bfe5a9ee0602a 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -170,25 +170,22 @@ public: if (seen.contains(typeInfoSym)) return; seen.insert(typeInfoSym); - if (!skipRegistration) { - registeredTypeInfo.emplace_back( - TypeInfo{typeInfoSym, typeSpec, type, loc}); - return; - } - // Once the registration is closed, symbols cannot be added to the - // registeredTypeInfoSymbols list because it may be iterated over. - // However, after registration is closed, it is safe to directly generate - // the globals because all FuncOps whose addresses may be required by the - // initializers have been generated. - createTypeInfoOpAndGlobal(converter, - TypeInfo{typeInfoSym, typeSpec, type, loc}); + currentTypeInfoStack->emplace_back( + TypeInfo{typeInfoSym, typeSpec, type, loc}); + return; } void createTypeInfo(Fortran::lower::AbstractConverter &converter) { - skipRegistration = true; - for (const TypeInfo &info : registeredTypeInfo) - createTypeInfoOpAndGlobal(converter, info); - registeredTypeInfo.clear(); + while (!registeredTypeInfoA.empty()) { + currentTypeInfoStack = ®isteredTypeInfoB; + for (const TypeInfo &info : registeredTypeInfoA) + createTypeInfoOpAndGlobal(converter, info); + registeredTypeInfoA.clear(); + currentTypeInfoStack = ®isteredTypeInfoA; + for (const TypeInfo &info : registeredTypeInfoB) + createTypeInfoOpAndGlobal(converter, info); + registeredTypeInfoB.clear(); + } } private: @@ -249,11 +246,12 @@ private: } /// Store the front-end data that will be required to generate the type info - /// for the derived types that have been converted to fir.type<>. - llvm::SmallVector registeredTypeInfo; - /// Create derived type info immediately without storing the - /// symbol in registeredTypeInfo. - bool skipRegistration = false; + /// for the derived types that have been converted to fir.type<>. There are + /// two stacks since the type info may visit new types, so the new types must + /// be added to a new stack. + llvm::SmallVector registeredTypeInfoA; + llvm::SmallVector registeredTypeInfoB; + llvm::SmallVector *currentTypeInfoStack = ®isteredTypeInfoA; /// Track symbols symbols processed during and after the registration /// to avoid infinite loops between type conversions and global variable /// creation. @@ -602,6 +600,11 @@ public: std::nullopt); } + Fortran::lower::TypeConstructionStack & + getTypeConstructionStack() override final { + return typeConstructionStack; + } + bool isPresentShallowLookup(Fortran::semantics::Symbol &sym) override final { return bool(shallowLookupSymbol(sym)); } @@ -839,6 +842,11 @@ public: } } + void genEval(Fortran::lower::pft::Evaluation &eval, + bool unstructuredContext) override final { + genFIR(eval, unstructuredContext); + } + //===--------------------------------------------------------------------===// // Utility methods //===--------------------------------------------------------------------===// @@ -2416,48 +2424,8 @@ private: void genFIR(const Fortran::parser::OpenMPConstruct &omp) { mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint(); - localSymbols.pushScope(); - genOpenMPConstruct(*this, bridge.getSemanticsContext(), getEval(), omp); - - const Fortran::parser::OpenMPLoopConstruct *ompLoop = - std::get_if(&omp.u); - const Fortran::parser::OpenMPBlockConstruct *ompBlock = - std::get_if(&omp.u); - - // If loop is part of an OpenMP Construct then the OpenMP dialect - // workshare loop operation has already been created. Only the - // body needs to be created here and the do_loop can be skipped. - // Skip the number of collapsed loops, which is 1 when there is a - // no collapse requested. - - Fortran::lower::pft::Evaluation *curEval = &getEval(); - const Fortran::parser::OmpClauseList *loopOpClauseList = nullptr; - if (ompLoop) { - loopOpClauseList = &std::get( - std::get(ompLoop->t).t); - int64_t collapseValue = - Fortran::lower::getCollapseValue(*loopOpClauseList); - - curEval = &curEval->getFirstNestedEvaluation(); - for (int64_t i = 1; i < collapseValue; i++) { - curEval = &*std::next(curEval->getNestedEvaluations().begin()); - } - } - - for (Fortran::lower::pft::Evaluation &e : curEval->getNestedEvaluations()) - genFIR(e); - - if (ompLoop) { - genOpenMPReduction(*this, *loopOpClauseList); - } else if (ompBlock) { - const auto &blockStart = - std::get(ompBlock->t); - const auto &blockClauses = - std::get(blockStart.t); - genOpenMPReduction(*this, blockClauses); - } - - localSymbols.popScope(); + genOpenMPConstruct(*this, localSymbols, bridge.getSemanticsContext(), + getEval(), omp); builder->restoreInsertionPoint(insertPt); // Register if a target region was found @@ -2473,8 +2441,6 @@ private: ompDeviceCodeFound || Fortran::lower::isOpenMPDeviceDeclareTarget(*this, getEval(), ompDecl); genOpenMPDeclarativeConstruct(*this, getEval(), ompDecl); - for (Fortran::lower::pft::Evaluation &e : getEval().getNestedEvaluations()) - genFIR(e); builder->restoreInsertionPoint(insertPt); } @@ -3126,6 +3092,10 @@ private: //===--------------------------------------------------------------------===// + void genFIR(const Fortran::parser::NotifyWaitStmt &stmt) { + genNotifyWaitStatement(*this, stmt); + } + void genFIR(const Fortran::parser::EventPostStmt &stmt) { genEventPostStatement(*this, stmt); } @@ -4238,15 +4208,8 @@ private: void instantiateVar(const Fortran::lower::pft::Variable &var, Fortran::lower::AggregateStoreMap &storeMap) { Fortran::lower::instantiateVariable(*this, var, localSymbols, storeMap); - if (var.hasSymbol()) { - if (var.getSymbol().test( - Fortran::semantics::Symbol::Flag::OmpThreadprivate)) - Fortran::lower::genThreadprivateOp(*this, var); - - if (var.getSymbol().test( - Fortran::semantics::Symbol::Flag::OmpDeclareTarget)) - Fortran::lower::genDeclareTargetIntGlobal(*this, var); - } + if (var.hasSymbol()) + genOpenMPSymbolProperties(*this, var); } /// Where applicable, save the exception state and halting and rounding @@ -5052,6 +5015,13 @@ private: bool ompDeviceCodeFound = false; const Fortran::lower::ExprToValueMap *exprValueOverrides{nullptr}; + + /// Stack of derived type under construction to avoid infinite loops when + /// dealing with recursive derived types. This is held in the bridge because + /// the state needs to be maintained between data and function type lowering + /// utilities to deal with procedure pointer components whose arguments have + /// the type of the containing derived type. + Fortran::lower::TypeConstructionStack typeConstructionStack; }; } // namespace diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 1f41c3bec847ecfd6d6126bd70b1b6b07b085b71..45487197fcbbbe78ffd26874c5139fc6c03d0aa3 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -87,6 +87,11 @@ bool Fortran::lower::CallerInterface::isIndirectCall() const { } bool Fortran::lower::CallerInterface::requireDispatchCall() const { + // Procedure pointer component reference do not require dispatch, but + // have PASS/NOPASS argument. + if (const Fortran::semantics::Symbol *sym = procRef.proc().GetSymbol()) + if (Fortran::semantics::IsPointer(*sym)) + return false; // calls with NOPASS attribute still have their component so check if it is // polymorphic. if (const Fortran::evaluate::Component *component = @@ -127,12 +132,21 @@ Fortran::lower::CallerInterface::getPassArgIndex() const { return passArg; } -const Fortran::semantics::Symbol * -Fortran::lower::CallerInterface::getIfIndirectCallSymbol() const { +mlir::Value Fortran::lower::CallerInterface::getIfPassedArg() const { + if (std::optional passArg = getPassArgIndex()) { + assert(actualInputs.size() > *passArg && actualInputs[*passArg] && + "passed arg was not set yet"); + return actualInputs[*passArg]; + } + return {}; +} + +const Fortran::evaluate::ProcedureDesignator * +Fortran::lower::CallerInterface::getIfIndirectCall() const { if (const Fortran::semantics::Symbol *symbol = procRef.proc().GetSymbol()) if (Fortran::semantics::IsPointer(*symbol) || Fortran::semantics::IsDummy(*symbol)) - return symbol; + return &procRef.proc(); return nullptr; } diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index 49e70181a668c6029c3d2e3651125188d9fcc272..57ac9d0652b3176500899c62cb62fc67600cbbb1 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -13,6 +13,7 @@ #include "flang/Lower/ConvertCall.h" #include "flang/Lower/Allocatable.h" #include "flang/Lower/ConvertExprToHLFIR.h" +#include "flang/Lower/ConvertProcedureDesignator.h" #include "flang/Lower/ConvertVariable.h" #include "flang/Lower/CustomIntrinsicCall.h" #include "flang/Lower/HlfirIntrinsics.h" @@ -165,20 +166,28 @@ fir::ExtendedValue Fortran::lower::genCallOpAndResult( // will be used only if there is no explicit length in the local interface). mlir::Value funcPointer; mlir::Value charFuncPointerLength; - if (const Fortran::semantics::Symbol *sym = - caller.getIfIndirectCallSymbol()) { - funcPointer = fir::getBase(converter.getSymbolExtendedValue(*sym, &symMap)); - if (!funcPointer) - fir::emitFatalError(loc, "failed to find indirect call symbol address"); - if (fir::isCharacterProcedureTuple(funcPointer.getType(), - /*acceptRawFunc=*/false)) - std::tie(funcPointer, charFuncPointerLength) = - fir::factory::extractCharacterProcedureTuple(builder, loc, - funcPointer); - // Reference to a procedure pointer. Load its value, the address of the - // procedure it points to. - if (Fortran::semantics::IsProcedurePointer(sym)) - funcPointer = builder.create(loc, funcPointer); + if (const Fortran::evaluate::ProcedureDesignator *procDesignator = + caller.getIfIndirectCall()) { + if (mlir::Value passedArg = caller.getIfPassedArg()) { + // Procedure pointer component call with PASS argument. To avoid + // "double" lowering of the ComponentRef, semantics only place the + // ComponentRef in the ActualArguments, not in the ProcedureDesignator ( + // that is only the component symbol). + // Fetch the passed argument and addresses of its procedure pointer + // component. + funcPointer = Fortran::lower::derefPassProcPointerComponent( + loc, converter, *procDesignator, passedArg, symMap, stmtCtx); + } else { + Fortran::lower::SomeExpr expr{*procDesignator}; + fir::ExtendedValue loweredProc = + converter.genExprAddr(loc, expr, stmtCtx); + funcPointer = fir::getBase(loweredProc); + // Dummy procedure may have assumed length, in which case the result + // length was passed along the dummy procedure. + // This is not possible with procedure pointer components. + if (const fir::CharBoxValue *charBox = loweredProc.getCharBox()) + charFuncPointerLength = charBox->getLen(); + } } mlir::IndexType idxTy = builder.getIndexType(); @@ -878,7 +887,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument( // Handle the procedure pointer actual arguments. if (actual.isProcedurePointer()) { // Procedure pointer actual to procedure pointer dummy. - if (hlfir::isBoxProcAddressType(dummyType)) + if (fir::isBoxProcAddressType(dummyType)) return PreparedDummyArgument{actual, /*cleanups=*/{}}; // Procedure pointer actual to procedure dummy. if (hlfir::isFortranProcedureValue(dummyType)) { @@ -889,7 +898,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument( // NULL() actual to procedure pointer dummy if (Fortran::evaluate::IsNullProcedurePointer(expr) && - hlfir::isBoxProcAddressType(dummyType)) { + fir::isBoxProcAddressType(dummyType)) { auto boxTy{Fortran::lower::getUntypedBoxProcType(builder.getContext())}; auto tempBoxProc{builder.createTemporary(loc, boxTy)}; hlfir::Entity nullBoxProc( @@ -900,7 +909,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument( if (actual.isProcedure()) { // Procedure actual to procedure pointer dummy. - if (hlfir::isBoxProcAddressType(dummyType)) { + if (fir::isBoxProcAddressType(dummyType)) { auto tempBoxProc{builder.createTemporary(loc, actual.getType())}; builder.create(loc, actual, tempBoxProc); return PreparedDummyArgument{tempBoxProc, /*cleanups=*/{}}; @@ -1546,8 +1555,6 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals, } hlfir::Entity actual = arg.value()->getActual(loc, builder); - if (actual.isProcedurePointer()) - TODO(loc, "Procedure pointer as actual argument to intrinsics."); switch (argRules.lowerAs) { case fir::LowerIntrinsicArgAs::Value: operands.emplace_back( diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp index 56ca7ab2d93103c1d24ed5df641b700021252827..d7a4d68f2aaae77aa253c4128e12fa2ba7e3029f 100644 --- a/flang/lib/Lower/ConvertConstant.cpp +++ b/flang/lib/Lower/ConvertConstant.cpp @@ -366,6 +366,8 @@ static mlir::Value genStructureComponentInit( TODO(loc, "allocatable component in structure constructor"); if (Fortran::semantics::IsPointer(sym)) { + if (Fortran::semantics::IsProcedure(sym)) + TODO(loc, "procedure pointer component initial value"); mlir::Value initialTarget = Fortran::lower::genInitialDataTarget(converter, loc, componentTy, expr); res = builder.create( diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp index 34e77581fca33811c8729d6a5bb0bef4b3996259..a2b28aa2e049128946c67a8ac2cd6a92e0a2f810 100644 --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -4849,7 +4849,7 @@ private: } } - if (caller.getIfIndirectCallSymbol()) + if (caller.getIfIndirectCall()) fir::emitFatalError(loc, "cannot be indirect call"); // The lambda is mutable so that `caller` copy can be modified inside it. diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 7771b4a635f293b790446264f77d2359ed9b6d3f..a3ad10978e598619e1a879ed6d615e2f6997093d 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -1738,6 +1738,8 @@ private: if (attrs && bitEnumContainsAny(attrs.getFlags(), fir::FortranVariableFlagsEnum::pointer)) { + if (Fortran::semantics::IsProcedure(sym)) + TODO(loc, "procedure pointer component in structure constructor"); // Pointer component construction is just a copy of the box contents. fir::ExtendedValue lhsExv = hlfir::translateToExtendedValue(loc, builder, lhs); diff --git a/flang/lib/Lower/ConvertProcedureDesignator.cpp b/flang/lib/Lower/ConvertProcedureDesignator.cpp index 84e04b0a65f447ed5ee5239ea40c563c2dabbcc1..0806f78450dd6f180da98c518c1409b25dffe39b 100644 --- a/flang/lib/Lower/ConvertProcedureDesignator.cpp +++ b/flang/lib/Lower/ConvertProcedureDesignator.cpp @@ -19,6 +19,7 @@ #include "flang/Optimizer/Builder/IntrinsicCall.h" #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/HLFIR/HLFIROps.h" static bool areAllSymbolsInExprMapped(const Fortran::evaluate::ExtentExpr &expr, Fortran::lower::SymMap &symMap) { @@ -96,6 +97,49 @@ fir::ExtendedValue Fortran::lower::convertProcedureDesignator( return funcPtr; } +static hlfir::EntityWithAttributes designateProcedurePointerComponent( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + const Fortran::evaluate::Symbol &procComponentSym, mlir::Value base, + Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + fir::FortranVariableFlagsAttr attributes = + Fortran::lower::translateSymbolAttributes(builder.getContext(), + procComponentSym); + /// Passed argument may be a descriptor. This is a scalar reference, so the + /// base address can be directly addressed. + if (base.getType().isa()) + base = builder.create(loc, base); + std::string fieldName = converter.getRecordTypeFieldName(procComponentSym); + auto recordType = + hlfir::getFortranElementType(base.getType()).cast(); + mlir::Type fieldType = recordType.getType(fieldName); + // FIXME: semantics is not expanding intermediate parent components in: + // call x%p() where p is a component of a parent type of x type. + if (!fieldType) + TODO(loc, "reference to procedure pointer component from parent type"); + mlir::Type designatorType = fir::ReferenceType::get(fieldType); + mlir::Value compRef = builder.create( + loc, designatorType, base, fieldName, + /*compShape=*/mlir::Value{}, hlfir::DesignateOp::Subscripts{}, + /*substring=*/mlir::ValueRange{}, + /*complexPart=*/std::nullopt, + /*shape=*/mlir::Value{}, /*typeParams=*/mlir::ValueRange{}, attributes); + return hlfir::EntityWithAttributes{compRef}; +} + +static hlfir::EntityWithAttributes convertProcedurePointerComponent( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + const Fortran::evaluate::Component &procComponent, + Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) { + fir::ExtendedValue baseExv = Fortran::lower::convertDataRefToValue( + loc, converter, procComponent.base(), symMap, stmtCtx); + mlir::Value base = fir::getBase(baseExv); + const Fortran::semantics::Symbol &procComponentSym = + procComponent.GetLastSymbol(); + return designateProcedurePointerComponent(loc, converter, procComponentSym, + base, symMap, stmtCtx); +} + hlfir::EntityWithAttributes Fortran::lower::convertProcedureDesignatorToHLFIR( mlir::Location loc, Fortran::lower::AbstractConverter &converter, const Fortran::evaluate::ProcedureDesignator &proc, @@ -109,6 +153,10 @@ hlfir::EntityWithAttributes Fortran::lower::convertProcedureDesignatorToHLFIR( return *varDef; } + if (const Fortran::evaluate::Component *procComponent = proc.GetComponent()) + return convertProcedurePointerComponent(loc, converter, *procComponent, + symMap, stmtCtx); + fir::ExtendedValue procExv = convertProcedureDesignator(loc, converter, proc, symMap, stmtCtx); // Directly package the procedure address as a fir.boxproc or @@ -148,3 +196,15 @@ mlir::Value Fortran::lower::convertProcedureDesignatorInitialTarget( return fir::getBase(Fortran::lower::convertToAddress( loc, converter, procVal, stmtCtx, procVal.getType())); } + +mlir::Value Fortran::lower::derefPassProcPointerComponent( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + const Fortran::evaluate::ProcedureDesignator &proc, mlir::Value passedArg, + Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) { + const Fortran::semantics::Symbol *procComponentSym = proc.GetSymbol(); + assert(procComponentSym && + "failed to retrieve pointer procedure component symbol"); + hlfir::EntityWithAttributes pointerComp = designateProcedurePointerComponent( + loc, converter, *procComponentSym, passedArg, symMap, stmtCtx); + return converter.getFirOpBuilder().create(loc, pointerComp); +} diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index 72f1ee7a2cb2baa661c3643e92542a5233b3463b..8caafb72e472a543f09ac6bac43a5cdc7092b0ed 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -140,7 +140,8 @@ namespace { struct TypeBuilderImpl { TypeBuilderImpl(Fortran::lower::AbstractConverter &converter) - : converter{converter}, context{&converter.getMLIRContext()} {} + : derivedTypeInConstruction{converter.getTypeConstructionStack()}, + converter{converter}, context{&converter.getMLIRContext()} {} template mlir::Type genExprType(const A &expr) { @@ -398,8 +399,6 @@ struct TypeBuilderImpl { assert(scopeIter != derivedScope.cend() && "failed to find derived type component symbol"); const Fortran::semantics::Symbol &component = scopeIter->second.get(); - if (IsProcedure(component)) - TODO(converter.genLocation(component.name()), "procedure components"); mlir::Type ty = genSymbolType(component); cs.emplace_back(converter.getRecordTypeFieldName(component), ty); } @@ -568,8 +567,7 @@ struct TypeBuilderImpl { /// Stack derived type being processed to avoid infinite loops in case of /// recursive derived types. The depth of derived types is expected to be /// shallow (<10), so a SmallVector is sufficient. - llvm::SmallVector> - derivedTypeInConstruction; + Fortran::lower::TypeConstructionStack &derivedTypeInConstruction; Fortran::lower::AbstractConverter &converter; mlir::MLIRContext *context; }; diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 364de33d00a627abc12958ad2bc68ca4221636b9..ad44de71ee828a868931d6e77031cda7889cd9cb 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -238,6 +238,10 @@ mlir::Value Fortran::lower::genInitialDataTarget( /*nonDeferredParams=*/std::nullopt); // Pointer initial data target, and NULL(mold). for (const auto &sym : Fortran::evaluate::CollectSymbols(initialTarget)) { + // Derived type component symbols should not be instantiated as objects + // on their own. + if (sym->owner().IsDerivedType()) + continue; // Length parameters processing will need care in global initializer // context. if (hasDerivedTypeWithLengthParameters(sym)) diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 88a8916663df7514426a81249e04199469ba000c..ffbd8ae1558ed5b5696c871786dc8de96fcd64f0 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -47,6 +47,17 @@ namespace Fortran { namespace lower { +/// Information gathered to generate bounds operation and data entry/exit +/// operations. +struct AddrAndBoundsInfo { + explicit AddrAndBoundsInfo() {} + explicit AddrAndBoundsInfo(mlir::Value addr) : addr(addr) {} + explicit AddrAndBoundsInfo(mlir::Value addr, mlir::Value isPresent) + : addr(addr), isPresent(isPresent) {} + mlir::Value addr = nullptr; + mlir::Value isPresent = nullptr; +}; + /// Checks if the assignment statement has a single variable on the RHS. static inline bool checkForSingleVariableOnRHS( const Fortran::parser::AssignmentStmt &assignmentStmt) { @@ -598,7 +609,7 @@ void createEmptyRegionBlocks( } } -inline mlir::Value +inline AddrAndBoundsInfo getDataOperandBaseAddr(Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder, Fortran::lower::SymbolRef sym, mlir::Location loc) { @@ -620,25 +631,42 @@ getDataOperandBaseAddr(Fortran::lower::AbstractConverter &converter, // Load the box when baseAddr is a `fir.ref>` or a // `fir.ref>` type. - if (symAddr.getType().isa()) - return builder.create(loc, symAddr); + if (symAddr.getType().isa()) { + if (Fortran::semantics::IsOptional(sym)) { + mlir::Value isPresent = + builder.create(loc, builder.getI1Type(), symAddr); + mlir::Value addr = + builder.genIfOp(loc, {boxTy}, isPresent, /*withElseRegion=*/true) + .genThen([&]() { + mlir::Value load = builder.create(loc, symAddr); + builder.create(loc, mlir::ValueRange{load}); + }) + .genElse([&] { + mlir::Value absent = + builder.create(loc, boxTy); + builder.create(loc, mlir::ValueRange{absent}); + }) + .getResults()[0]; + return AddrAndBoundsInfo(addr, isPresent); + } + mlir::Value addr = builder.create(loc, symAddr); + return AddrAndBoundsInfo(addr); + ; + } } - return symAddr; + return AddrAndBoundsInfo(symAddr); } -/// Generate the bounds operation from the descriptor information. template llvm::SmallVector -genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, - Fortran::lower::AbstractConverter &converter, - fir::ExtendedValue dataExv, mlir::Value box) { - llvm::SmallVector bounds; +gatherBoundsOrBoundValues(fir::FirOpBuilder &builder, mlir::Location loc, + fir::ExtendedValue dataExv, mlir::Value box, + bool collectValuesOnly = false) { + llvm::SmallVector values; + mlir::Value byteStride; mlir::Type idxTy = builder.getIndexType(); mlir::Type boundTy = builder.getType(); mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); - assert(box.getType().isa() && - "expect fir.box or fir.class"); - mlir::Value byteStride; for (unsigned dim = 0; dim < dataExv.rank(); ++dim) { mlir::Value d = builder.createIntegerConstant(loc, idxTy, dim); mlir::Value baseLb = @@ -650,12 +678,79 @@ genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, builder.create(loc, dimInfo.getExtent(), one); if (dim == 0) // First stride is the element size. byteStride = dimInfo.getByteStride(); - mlir::Value bound = builder.create( - loc, boundTy, lb, ub, dimInfo.getExtent(), byteStride, true, baseLb); + if (collectValuesOnly) { + values.push_back(lb); + values.push_back(ub); + values.push_back(dimInfo.getExtent()); + values.push_back(byteStride); + values.push_back(baseLb); + } else { + mlir::Value bound = builder.create( + loc, boundTy, lb, ub, dimInfo.getExtent(), byteStride, true, baseLb); + values.push_back(bound); + } // Compute the stride for the next dimension. byteStride = builder.create(loc, byteStride, dimInfo.getExtent()); - bounds.push_back(bound); + } + return values; +} + +/// Generate the bounds operation from the descriptor information. +template +llvm::SmallVector +genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, + Fortran::lower::AbstractConverter &converter, + fir::ExtendedValue dataExv, + Fortran::lower::AddrAndBoundsInfo &info) { + llvm::SmallVector bounds; + mlir::Type idxTy = builder.getIndexType(); + mlir::Type boundTy = builder.getType(); + + assert(info.addr.getType().isa() && + "expect fir.box or fir.class"); + + if (info.isPresent) { + llvm::SmallVector resTypes; + constexpr unsigned nbValuesPerBound = 5; + for (unsigned dim = 0; dim < dataExv.rank() * nbValuesPerBound; ++dim) + resTypes.push_back(idxTy); + + mlir::Operation::result_range ifRes = + builder.genIfOp(loc, resTypes, info.isPresent, /*withElseRegion=*/true) + .genThen([&]() { + llvm::SmallVector boundValues = + gatherBoundsOrBoundValues( + builder, loc, dataExv, info.addr, + /*collectValuesOnly=*/true); + builder.create(loc, boundValues); + }) + .genElse([&] { + // Box is not present. Populate bound values with default values. + llvm::SmallVector boundValues; + mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0); + mlir::Value mOne = builder.createIntegerConstant(loc, idxTy, -1); + for (unsigned dim = 0; dim < dataExv.rank(); ++dim) { + boundValues.push_back(zero); // lb + boundValues.push_back(mOne); // ub + boundValues.push_back(zero); // extent + boundValues.push_back(zero); // byteStride + boundValues.push_back(zero); // baseLb + } + builder.create(loc, boundValues); + }) + .getResults(); + // Create the bound operations outside the if-then-else with the if op + // results. + for (unsigned i = 0; i < ifRes.size(); i += nbValuesPerBound) { + mlir::Value bound = builder.create( + loc, boundTy, ifRes[i], ifRes[i + 1], ifRes[i + 2], ifRes[i + 3], + true, ifRes[i + 4]); + bounds.push_back(bound); + } + } else { + bounds = gatherBoundsOrBoundValues( + builder, loc, dataExv, info.addr); } return bounds; } @@ -666,7 +761,7 @@ template llvm::SmallVector genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, - fir::ExtendedValue dataExv, mlir::Value baseAddr) { + fir::ExtendedValue dataExv) { mlir::Type idxTy = builder.getIndexType(); mlir::Type boundTy = builder.getType(); llvm::SmallVector bounds; @@ -843,14 +938,13 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, } template -mlir::Value gatherDataOperandAddrAndBounds( +AddrAndBoundsInfo gatherDataOperandAddrAndBounds( Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder, Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::StatementContext &stmtCtx, const ObjectType &object, mlir::Location operandLocation, std::stringstream &asFortran, llvm::SmallVector &bounds, bool treatIndexAsSection = false) { - mlir::Value baseAddr; - + AddrAndBoundsInfo info; std::visit( Fortran::common::visitors{ [&](const Fortran::parser::Designator &designator) { @@ -872,42 +966,48 @@ mlir::Value gatherDataOperandAddrAndBounds( semanticsContext, arrayElement->base); dataExv = converter.genExprAddr(operandLocation, *exprBase, stmtCtx); - baseAddr = fir::getBase(dataExv); + info.addr = fir::getBase(dataExv); asFortran << (*exprBase).AsFortran(); } else { const Fortran::parser::Name &name = Fortran::parser::GetLastName(*dataRef); - baseAddr = getDataOperandBaseAddr( - converter, builder, *name.symbol, operandLocation); + info = getDataOperandBaseAddr(converter, builder, + *name.symbol, operandLocation); dataExv = converter.getSymbolExtendedValue(*name.symbol); asFortran << name.ToString(); } if (!arrayElement->subscripts.empty()) { asFortran << '('; - bounds = genBoundsOps( + bounds = genBoundsOps( builder, operandLocation, converter, stmtCtx, - arrayElement->subscripts, asFortran, dataExv, baseAddr, + arrayElement->subscripts, asFortran, dataExv, info.addr, treatIndexAsSection); } asFortran << ')'; - } else if (Fortran::parser::Unwrap< + } else if (auto structComp = Fortran::parser::Unwrap< Fortran::parser::StructureComponent>(designator)) { fir::ExtendedValue compExv = converter.genExprAddr(operandLocation, *expr, stmtCtx); - baseAddr = fir::getBase(compExv); - if (fir::unwrapRefType(baseAddr.getType()) + info.addr = fir::getBase(compExv); + if (fir::unwrapRefType(info.addr.getType()) .isa()) - bounds = genBaseBoundsOps( - builder, operandLocation, converter, compExv, baseAddr); + bounds = genBaseBoundsOps( + builder, operandLocation, converter, compExv); asFortran << (*expr).AsFortran(); + bool isOptional = Fortran::semantics::IsOptional( + *Fortran::parser::GetLastName(*structComp).symbol); + if (isOptional) + info.isPresent = builder.create( + operandLocation, builder.getI1Type(), info.addr); + if (auto loadOp = mlir::dyn_cast_or_null( - baseAddr.getDefiningOp())) { + info.addr.getDefiningOp())) { if (fir::isAllocatableType(loadOp.getType()) || fir::isPointerType(loadOp.getType())) - baseAddr = builder.create(operandLocation, - baseAddr); + info.addr = builder.create(operandLocation, + info.addr); } // If the component is an allocatable or pointer the result of @@ -915,10 +1015,10 @@ mlir::Value gatherDataOperandAddrAndBounds( // a fir.box_addr has been inserted just before. // Retrieve the box so we handle it like other descriptor. if (auto boxAddrOp = mlir::dyn_cast_or_null( - baseAddr.getDefiningOp())) { - baseAddr = boxAddrOp.getVal(); - bounds = genBoundsOpsFromBox( - builder, operandLocation, converter, compExv, baseAddr); + info.addr.getDefiningOp())) { + info.addr = boxAddrOp.getVal(); + bounds = genBoundsOpsFromBox( + builder, operandLocation, converter, compExv, info); } } else { if (Fortran::parser::Unwrap( @@ -930,7 +1030,7 @@ mlir::Value gatherDataOperandAddrAndBounds( (void)arrayElement; fir::ExtendedValue compExv = converter.genExprAddr(operandLocation, *expr, stmtCtx); - baseAddr = fir::getBase(compExv); + info.addr = fir::getBase(compExv); asFortran << (*expr).AsFortran(); } else if (const auto *dataRef{ std::get_if( @@ -940,16 +1040,17 @@ mlir::Value gatherDataOperandAddrAndBounds( Fortran::parser::GetLastName(*dataRef); fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(*name.symbol); - baseAddr = getDataOperandBaseAddr( - converter, builder, *name.symbol, operandLocation); - if (fir::unwrapRefType(baseAddr.getType()) - .isa()) - bounds = genBoundsOpsFromBox( - builder, operandLocation, converter, dataExv, baseAddr); - if (fir::unwrapRefType(baseAddr.getType()) + info = getDataOperandBaseAddr(converter, builder, + *name.symbol, operandLocation); + if (fir::unwrapRefType(info.addr.getType()) + .isa()) { + bounds = genBoundsOpsFromBox( + builder, operandLocation, converter, dataExv, info); + } + if (fir::unwrapRefType(info.addr.getType()) .isa()) - bounds = genBaseBoundsOps( - builder, operandLocation, converter, dataExv, baseAddr); + bounds = genBaseBoundsOps( + builder, operandLocation, converter, dataExv); asFortran << name.ToString(); } else { // Unsupported llvm::report_fatal_error( @@ -959,12 +1060,12 @@ mlir::Value gatherDataOperandAddrAndBounds( } }, [&](const Fortran::parser::Name &name) { - baseAddr = getDataOperandBaseAddr(converter, builder, *name.symbol, - operandLocation); + info = getDataOperandBaseAddr(converter, builder, *name.symbol, + operandLocation); asFortran << name.ToString(); }}, object.u); - return baseAddr; + return info; } } // namespace lower diff --git a/flang/lib/Lower/HlfirIntrinsics.cpp b/flang/lib/Lower/HlfirIntrinsics.cpp index 6e5ba92bee86a7c8db56d209405aa712424b4163..bda04fa9689beb4c08589a2978d4598826912c8b 100644 --- a/flang/lib/Lower/HlfirIntrinsics.cpp +++ b/flang/lib/Lower/HlfirIntrinsics.cpp @@ -105,6 +105,7 @@ protected: mlir::Type stmtResultType) override; }; using HlfirMinlocLowering = HlfirMinMaxLocIntrinsic; +using HlfirMaxlocLowering = HlfirMinMaxLocIntrinsic; template class HlfirProductIntrinsic : public HlfirTransformationalIntrinsic { @@ -373,9 +374,8 @@ mlir::Value HlfirCountLowering::lowerImpl( mlir::Value dim = operands[1]; if (dim) dim = hlfir::loadTrivialScalar(loc, builder, hlfir::Entity{dim}); - mlir::Value kind = operands[2]; mlir::Type resultType = computeResultType(array, stmtResultType); - return createOp(resultType, array, dim, kind); + return createOp(resultType, array, dim); } mlir::Value HlfirCharExtremumLowering::lowerImpl( @@ -429,6 +429,9 @@ std::optional Fortran::lower::lowerHlfirIntrinsic( if (name == "minloc") return HlfirMinlocLowering{builder, loc}.lower(loweredActuals, argLowering, stmtResultType); + if (name == "maxloc") + return HlfirMaxlocLowering{builder, loc}.lower(loweredActuals, argLowering, + stmtResultType); if (mlir::isa(stmtResultType)) { if (name == "min") return HlfirCharExtremumLowering{builder, loc, diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp index 4186d6158fb1d040aa994f32aba22ee4a4ae0277..3933ebeb9b3cc7c132943eac8f018a55adc08d44 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -641,7 +641,8 @@ static void genNamelistIO(Fortran::lower::AbstractConverter &converter, mlir::Location loc = converter.getCurrentLocation(); makeNextConditionalOn(builder, loc, checkResult, ok); mlir::Type argType = funcOp.getFunctionType().getInput(1); - mlir::Value groupAddr = getNamelistGroup(converter, symbol, stmtCtx); + mlir::Value groupAddr = + getNamelistGroup(converter, symbol.GetUltimate(), stmtCtx); groupAddr = builder.createConvert(loc, argType, groupAddr); llvm::SmallVector args = {cookie, groupAddr}; ok = builder.create(loc, funcOp, args).getResult(0); @@ -1849,24 +1850,25 @@ static mlir::Value genIOUnit(Fortran::lower::AbstractConverter &converter, mlir::Location loc, const Fortran::parser::IoUnit *iounit, mlir::Type ty, ConditionSpecInfo &csi, - Fortran::lower::StatementContext &stmtCtx) { + Fortran::lower::StatementContext &stmtCtx, + int defaultUnitNumber) { auto &builder = converter.getFirOpBuilder(); if (iounit) if (auto *e = std::get_if(&iounit->u)) return genIOUnitNumber(converter, loc, Fortran::semantics::GetExpr(*e), ty, csi, stmtCtx); return builder.create( - loc, builder.getIntegerAttr(ty, Fortran::runtime::io::DefaultUnit)); + loc, builder.getIntegerAttr(ty, defaultUnitNumber)); } template -static mlir::Value getIOUnit(Fortran::lower::AbstractConverter &converter, - mlir::Location loc, const A &stmt, mlir::Type ty, - ConditionSpecInfo &csi, - Fortran::lower::StatementContext &stmtCtx) { +static mlir::Value +getIOUnit(Fortran::lower::AbstractConverter &converter, mlir::Location loc, + const A &stmt, mlir::Type ty, ConditionSpecInfo &csi, + Fortran::lower::StatementContext &stmtCtx, int defaultUnitNumber) { const Fortran::parser::IoUnit *iounit = stmt.iounit ? &*stmt.iounit : getIOControl(stmt); - return genIOUnit(converter, loc, iounit, ty, csi, stmtCtx); + return genIOUnit(converter, loc, iounit, ty, csi, stmtCtx, defaultUnitNumber); } //===----------------------------------------------------------------------===// // Generators for each IO statement type. @@ -2090,7 +2092,7 @@ getBeginDataTransferFunc(mlir::Location loc, fir::FirOpBuilder &builder, } /// Generate the arguments of a begin data transfer statement call. -template +template void genBeginDataTransferCallArgs( llvm::SmallVectorImpl &ioArgs, Fortran::lower::AbstractConverter &converter, mlir::Location loc, @@ -2148,14 +2150,14 @@ void genBeginDataTransferCallArgs( TODO(loc, "asynchronous"); maybeGetFormatArgs(); ioArgs.push_back(getIOUnit(converter, loc, stmt, - ioFuncTy.getInput(ioArgs.size()), csi, - stmtCtx)); + ioFuncTy.getInput(ioArgs.size()), csi, stmtCtx, + defaultUnitNumber)); } } else { // PRINT - maybe explicit format; default unit maybeGetFormatArgs(); ioArgs.push_back(builder.create( loc, builder.getIntegerAttr(ioFuncTy.getInput(ioArgs.size()), - Fortran::runtime::io::DefaultUnit))); + defaultUnitNumber))); } // File name and line number are always the last two arguments. ioArgs.push_back( @@ -2192,7 +2194,9 @@ genDataTransferStmt(Fortran::lower::AbstractConverter &converter, loc, builder, isFormatted, isList || isNml, isInternal, isInternalWithDesc, isAsync); llvm::SmallVector ioArgs; - genBeginDataTransferCallArgs( + genBeginDataTransferCallArgs< + hasIOCtrl, isInput ? Fortran::runtime::io::DefaultInputUnit + : Fortran::runtime::io::DefaultOutputUnit>( ioArgs, converter, loc, stmt, ioFunc.getFunctionType(), isFormatted, isList || isNml, isInternal, isAsync, descRef, csi, stmtCtx); mlir::Value cookie = diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index e2abed1b9f4f67590b2fbc7e6fb4c4cda90a7543..ecf70818c4ac0f17e5476d0263559cb3d733bb6e 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -62,11 +62,29 @@ static Op createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value baseAddr, std::stringstream &name, mlir::SmallVector bounds, bool structured, bool implicit, - mlir::acc::DataClause dataClause, - mlir::Type retTy) { + mlir::acc::DataClause dataClause, mlir::Type retTy, + mlir::Value isPresent = {}) { mlir::Value varPtrPtr; if (auto boxTy = baseAddr.getType().dyn_cast()) { - baseAddr = builder.create(loc, baseAddr); + if (isPresent) { + baseAddr = + builder + .genIfOp(loc, {boxTy.getEleTy()}, isPresent, + /*withElseRegion=*/true) + .genThen([&]() { + mlir::Value boxAddr = + builder.create(loc, baseAddr); + builder.create(loc, mlir::ValueRange{boxAddr}); + }) + .genElse([&] { + mlir::Value absent = + builder.create(loc, boxTy.getEleTy()); + builder.create(loc, mlir::ValueRange{absent}); + }) + .getResults()[0]; + } else { + baseAddr = builder.create(loc, baseAddr); + } retTy = baseAddr.getType(); } @@ -200,14 +218,18 @@ static void createDeclareDeallocFuncWithArg( builder.create( loc, mlir::Value{}, mlir::ValueRange(entryOp.getAccPtr())); - mlir::Value varPtr; if constexpr (std::is_same_v || std::is_same_v) - varPtr = entryOp.getVarPtr(); - builder.create(entryOp.getLoc(), entryOp.getAccPtr(), varPtr, - entryOp.getBounds(), entryOp.getDataClause(), - /*structured=*/false, /*implicit=*/false, - builder.getStringAttr(*entryOp.getName())); + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), + entryOp.getVarPtr(), entryOp.getBounds(), + entryOp.getDataClause(), + /*structured=*/false, /*implicit=*/false, + builder.getStringAttr(*entryOp.getName())); + else + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), + entryOp.getBounds(), entryOp.getDataClause(), + /*structured=*/false, /*implicit=*/false, + builder.getStringAttr(*entryOp.getName())); // Generate the post dealloc function. modBuilder.setInsertionPointAfter(preDeallocOp); @@ -265,14 +287,17 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, llvm::SmallVector bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); - mlir::Value baseAddr = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsType, - mlir::acc::DataBoundsOp>(converter, builder, semanticsContext, stmtCtx, - accObject, operandLocation, asFortran, bounds, - /*treatIndexAsSection=*/true); - Op op = createDataEntryOp(builder, operandLocation, baseAddr, asFortran, - bounds, structured, implicit, dataClause, - baseAddr.getType()); + Fortran::lower::AddrAndBoundsInfo info = + Fortran::lower::gatherDataOperandAddrAndBounds< + Fortran::parser::AccObject, mlir::acc::DataBoundsOp, + mlir::acc::DataBoundsType>(converter, builder, semanticsContext, + stmtCtx, accObject, operandLocation, + asFortran, bounds, + /*treatIndexAsSection=*/true); + + Op op = createDataEntryOp( + builder, operandLocation, info.addr, asFortran, bounds, structured, + implicit, dataClause, info.addr.getType(), info.isPresent); dataOperands.push_back(op.getAccPtr()); } } @@ -290,26 +315,28 @@ static void genDeclareDataOperandOperations( llvm::SmallVector bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); - mlir::Value baseAddr = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsType, - mlir::acc::DataBoundsOp>(converter, builder, semanticsContext, stmtCtx, - accObject, operandLocation, asFortran, bounds); + Fortran::lower::AddrAndBoundsInfo info = + Fortran::lower::gatherDataOperandAddrAndBounds< + Fortran::parser::AccObject, mlir::acc::DataBoundsOp, + mlir::acc::DataBoundsType>(converter, builder, semanticsContext, + stmtCtx, accObject, operandLocation, + asFortran, bounds); EntryOp op = createDataEntryOp( - builder, operandLocation, baseAddr, asFortran, bounds, structured, - implicit, dataClause, baseAddr.getType()); + builder, operandLocation, info.addr, asFortran, bounds, structured, + implicit, dataClause, info.addr.getType()); dataOperands.push_back(op.getAccPtr()); addDeclareAttr(builder, op.getVarPtr().getDefiningOp(), dataClause); - if (mlir::isa(fir::unwrapRefType(baseAddr.getType()))) { + if (mlir::isa(fir::unwrapRefType(info.addr.getType()))) { mlir::OpBuilder modBuilder(builder.getModule().getBodyRegion()); modBuilder.setInsertionPointAfter(builder.getFunction()); std::string prefix = converter.mangleName(getSymbolFromAccObject(accObject)); createDeclareAllocFuncWithArg( - modBuilder, builder, operandLocation, baseAddr.getType(), prefix, + modBuilder, builder, operandLocation, info.addr.getType(), prefix, asFortran, dataClause); if constexpr (!std::is_same_v) createDeclareDeallocFuncWithArg( - modBuilder, builder, operandLocation, baseAddr.getType(), prefix, + modBuilder, builder, operandLocation, info.addr.getType(), prefix, asFortran, dataClause); } } @@ -345,14 +372,17 @@ static void genDataExitOperations(fir::FirOpBuilder &builder, for (mlir::Value operand : operands) { auto entryOp = mlir::dyn_cast_or_null(operand.getDefiningOp()); assert(entryOp && "data entry op expected"); - mlir::Value varPtr; if constexpr (std::is_same_v || std::is_same_v) - varPtr = entryOp.getVarPtr(); - builder.create(entryOp.getLoc(), entryOp.getAccPtr(), varPtr, - entryOp.getBounds(), entryOp.getDataClause(), - structured, entryOp.getImplicit(), - builder.getStringAttr(*entryOp.getName())); + builder.create( + entryOp.getLoc(), entryOp.getAccPtr(), entryOp.getVarPtr(), + entryOp.getBounds(), entryOp.getDataClause(), structured, + entryOp.getImplicit(), builder.getStringAttr(*entryOp.getName())); + else + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), + entryOp.getBounds(), entryOp.getDataClause(), + structured, entryOp.getImplicit(), + builder.getStringAttr(*entryOp.getName())); } } @@ -747,20 +777,21 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList, llvm::SmallVector bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); - mlir::Value baseAddr = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsType, - mlir::acc::DataBoundsOp>(converter, builder, semanticsContext, stmtCtx, - accObject, operandLocation, asFortran, bounds); - + Fortran::lower::AddrAndBoundsInfo info = + Fortran::lower::gatherDataOperandAddrAndBounds< + Fortran::parser::AccObject, mlir::acc::DataBoundsOp, + mlir::acc::DataBoundsType>(converter, builder, semanticsContext, + stmtCtx, accObject, operandLocation, + asFortran, bounds); RecipeOp recipe; - mlir::Type retTy = getTypeFromBounds(bounds, baseAddr.getType()); + mlir::Type retTy = getTypeFromBounds(bounds, info.addr.getType()); if constexpr (std::is_same_v) { std::string recipeName = fir::getTypeAsString(retTy, converter.getKindMap(), "privatization"); recipe = Fortran::lower::createOrGetPrivateRecipe(builder, recipeName, operandLocation, retTy); auto op = createDataEntryOp( - builder, operandLocation, baseAddr, asFortran, bounds, true, + builder, operandLocation, info.addr, asFortran, bounds, true, /*implicit=*/false, mlir::acc::DataClause::acc_private, retTy); dataOperands.push_back(op.getAccPtr()); } else { @@ -771,7 +802,7 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList, recipe = Fortran::lower::createOrGetFirstprivateRecipe( builder, recipeName, operandLocation, retTy, bounds); auto op = createDataEntryOp( - builder, operandLocation, baseAddr, asFortran, bounds, true, + builder, operandLocation, info.addr, asFortran, bounds, true, /*implicit=*/false, mlir::acc::DataClause::acc_firstprivate, retTy); dataOperands.push_back(op.getAccPtr()); } @@ -1323,12 +1354,14 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList, llvm::SmallVector bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); - mlir::Value baseAddr = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsType, - mlir::acc::DataBoundsOp>(converter, builder, semanticsContext, stmtCtx, - accObject, operandLocation, asFortran, bounds); - - mlir::Type reductionTy = fir::unwrapRefType(baseAddr.getType()); + Fortran::lower::AddrAndBoundsInfo info = + Fortran::lower::gatherDataOperandAddrAndBounds< + Fortran::parser::AccObject, mlir::acc::DataBoundsOp, + mlir::acc::DataBoundsType>(converter, builder, semanticsContext, + stmtCtx, accObject, operandLocation, + asFortran, bounds); + + mlir::Type reductionTy = fir::unwrapRefType(info.addr.getType()); if (auto seqTy = mlir::dyn_cast(reductionTy)) reductionTy = seqTy.getEleTy(); @@ -1336,14 +1369,14 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList, TODO(operandLocation, "reduction with unsupported type"); auto op = createDataEntryOp( - builder, operandLocation, baseAddr, asFortran, bounds, + builder, operandLocation, info.addr, asFortran, bounds, /*structured=*/true, /*implicit=*/false, - mlir::acc::DataClause::acc_reduction, baseAddr.getType()); + mlir::acc::DataClause::acc_reduction, info.addr.getType()); mlir::Type ty = op.getAccPtr().getType(); if (!areAllBoundConstant(bounds) || - fir::isAssumedShape(baseAddr.getType()) || - fir::isAllocatableOrPointerArray(baseAddr.getType())) - ty = baseAddr.getType(); + fir::isAssumedShape(info.addr.getType()) || + fir::isAllocatableOrPointerArray(info.addr.getType())) + ty = info.addr.getType(); std::string suffix = areAllBoundConstant(bounds) ? getBoundsString(bounds) : ""; std::string recipeName = fir::getTypeAsString( @@ -1447,7 +1480,7 @@ getDeviceType(Fortran::parser::AccDeviceTypeExpr::Device device) { case Fortran::parser::AccDeviceTypeExpr::Device::Multicore: return mlir::acc::DeviceType::Multicore; } - return mlir::acc::DeviceType::Default; + return mlir::acc::DeviceType::None; } static void gatherDeviceTypeAttrs( @@ -1748,26 +1781,24 @@ createComputeOp(Fortran::lower::AbstractConverter &converter, bool outerCombined = false) { // Parallel operation operands - mlir::Value async; - mlir::Value numWorkers; - mlir::Value vectorLength; mlir::Value ifCond; mlir::Value selfCond; - mlir::Value waitDevnum; llvm::SmallVector waitOperands, attachEntryOperands, copyEntryOperands, copyoutEntryOperands, createEntryOperands, - dataClauseOperands, numGangs; + dataClauseOperands, numGangs, numWorkers, vectorLength, async; + llvm::SmallVector numGangsDeviceTypes, numWorkersDeviceTypes, + vectorLengthDeviceTypes, asyncDeviceTypes, asyncOnlyDeviceTypes, + waitOperandsDeviceTypes, waitOnlyDeviceTypes; + llvm::SmallVector numGangsSegments, waitOperandsSegments; llvm::SmallVector reductionOperands, privateOperands, firstprivateOperands; llvm::SmallVector privatizations, firstPrivatizations, reductionRecipes; - // Async, wait and self clause have optional values but can be present with + // Self clause has optional values but can be present with // no value as well. When there is no value, the op has an attribute to // represent the clause. - bool addAsyncAttr = false; - bool addWaitAttr = false; bool addSelfAttr = false; bool hasDefaultNone = false; @@ -1775,6 +1806,11 @@ createComputeOp(Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + // device_type attribute is set to `none` until a device_type clause is + // encountered. + auto crtDeviceTypeAttr = mlir::acc::DeviceTypeAttr::get( + builder.getContext(), mlir::acc::DeviceType::None); + // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. @@ -1782,27 +1818,52 @@ createComputeOp(Fortran::lower::AbstractConverter &converter, mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *asyncClause = std::get_if(&clause.u)) { - genAsyncClause(converter, asyncClause, async, addAsyncAttr, stmtCtx); + const auto &asyncClauseValue = asyncClause->v; + if (asyncClauseValue) { // async has a value. + async.push_back(fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(*asyncClauseValue), stmtCtx))); + asyncDeviceTypes.push_back(crtDeviceTypeAttr); + } else { + asyncOnlyDeviceTypes.push_back(crtDeviceTypeAttr); + } } else if (const auto *waitClause = std::get_if(&clause.u)) { - genWaitClause(converter, waitClause, waitOperands, waitDevnum, - addWaitAttr, stmtCtx); + const auto &waitClauseValue = waitClause->v; + if (waitClauseValue) { // wait has a value. + const Fortran::parser::AccWaitArgument &waitArg = *waitClauseValue; + const auto &waitList = + std::get>(waitArg.t); + auto crtWaitOperands = waitOperands.size(); + for (const Fortran::parser::ScalarIntExpr &value : waitList) { + waitOperands.push_back(fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(value), stmtCtx))); + } + waitOperandsDeviceTypes.push_back(crtDeviceTypeAttr); + waitOperandsSegments.push_back(waitOperands.size() - crtWaitOperands); + } else { + waitOnlyDeviceTypes.push_back(crtDeviceTypeAttr); + } } else if (const auto *numGangsClause = std::get_if( &clause.u)) { + auto crtNumGangs = numGangs.size(); for (const Fortran::parser::ScalarIntExpr &expr : numGangsClause->v) numGangs.push_back(fir::getBase(converter.genExprValue( *Fortran::semantics::GetExpr(expr), stmtCtx))); + numGangsDeviceTypes.push_back(crtDeviceTypeAttr); + numGangsSegments.push_back(numGangs.size() - crtNumGangs); } else if (const auto *numWorkersClause = std::get_if( &clause.u)) { - numWorkers = fir::getBase(converter.genExprValue( - *Fortran::semantics::GetExpr(numWorkersClause->v), stmtCtx)); + numWorkers.push_back(fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(numWorkersClause->v), stmtCtx))); + numWorkersDeviceTypes.push_back(crtDeviceTypeAttr); } else if (const auto *vectorLengthClause = std::get_if( &clause.u)) { - vectorLength = fir::getBase(converter.genExprValue( - *Fortran::semantics::GetExpr(vectorLengthClause->v), stmtCtx)); + vectorLength.push_back(fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(vectorLengthClause->v), stmtCtx))); + vectorLengthDeviceTypes.push_back(crtDeviceTypeAttr); } else if (const auto *ifClause = std::get_if(&clause.u)) { genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); @@ -1953,18 +2014,27 @@ createComputeOp(Fortran::lower::AbstractConverter &converter, else if ((defaultClause->v).v == llvm::acc::DefaultValue::ACC_Default_present) hasDefaultPresent = true; + } else if (const auto *deviceTypeClause = + std::get_if( + &clause.u)) { + const Fortran::parser::AccDeviceTypeExprList &deviceTypeExprList = + deviceTypeClause->v; + assert(deviceTypeExprList.v.size() == 1 && + "expect only one device_type expr"); + crtDeviceTypeAttr = mlir::acc::DeviceTypeAttr::get( + builder.getContext(), getDeviceType(deviceTypeExprList.v.front().v)); } } // Prepare the operand segment size attribute and the operands value range. llvm::SmallVector operands; llvm::SmallVector operandSegments; - addOperand(operands, operandSegments, async); + addOperands(operands, operandSegments, async); addOperands(operands, operandSegments, waitOperands); if constexpr (!std::is_same_v) { addOperands(operands, operandSegments, numGangs); - addOperand(operands, operandSegments, numWorkers); - addOperand(operands, operandSegments, vectorLength); + addOperands(operands, operandSegments, numWorkers); + addOperands(operands, operandSegments, vectorLength); } addOperand(operands, operandSegments, ifCond); addOperand(operands, operandSegments, selfCond); @@ -1985,10 +2055,6 @@ createComputeOp(Fortran::lower::AbstractConverter &converter, builder, currentLocation, eval, operands, operandSegments, outerCombined); - if (addAsyncAttr) - computeOp.setAsyncAttrAttr(builder.getUnitAttr()); - if (addWaitAttr) - computeOp.setWaitAttrAttr(builder.getUnitAttr()); if (addSelfAttr) computeOp.setSelfAttrAttr(builder.getUnitAttr()); @@ -1997,6 +2063,34 @@ createComputeOp(Fortran::lower::AbstractConverter &converter, if (hasDefaultPresent) computeOp.setDefaultAttr(mlir::acc::ClauseDefaultValue::Present); + if constexpr (!std::is_same_v) { + if (!numWorkersDeviceTypes.empty()) + computeOp.setNumWorkersDeviceTypeAttr( + mlir::ArrayAttr::get(builder.getContext(), numWorkersDeviceTypes)); + if (!vectorLengthDeviceTypes.empty()) + computeOp.setVectorLengthDeviceTypeAttr( + mlir::ArrayAttr::get(builder.getContext(), vectorLengthDeviceTypes)); + if (!numGangsDeviceTypes.empty()) + computeOp.setNumGangsDeviceTypeAttr( + mlir::ArrayAttr::get(builder.getContext(), numGangsDeviceTypes)); + if (!numGangsSegments.empty()) + computeOp.setNumGangsSegmentsAttr( + builder.getDenseI32ArrayAttr(numGangsSegments)); + } + if (!asyncDeviceTypes.empty()) + computeOp.setAsyncDeviceTypeAttr(builder.getArrayAttr(asyncDeviceTypes)); + if (!asyncOnlyDeviceTypes.empty()) + computeOp.setAsyncOnlyAttr(builder.getArrayAttr(asyncOnlyDeviceTypes)); + + if (!waitOperandsDeviceTypes.empty()) + computeOp.setWaitOperandsDeviceTypeAttr( + builder.getArrayAttr(waitOperandsDeviceTypes)); + if (!waitOperandsSegments.empty()) + computeOp.setWaitOperandsSegmentsAttr( + builder.getDenseI32ArrayAttr(waitOperandsSegments)); + if (!waitOnlyDeviceTypes.empty()) + computeOp.setWaitOnlyAttr(builder.getArrayAttr(waitOnlyDeviceTypes)); + if constexpr (!std::is_same_v) { if (!privatizations.empty()) computeOp.setPrivatizationsAttr( @@ -2814,9 +2908,8 @@ static void createDeclareGlobalOp(mlir::OpBuilder &modBuilder, else builder.create(loc, mlir::Value{}, mlir::ValueRange(entryOp.getAccPtr())); - mlir::Value varPtr; if constexpr (std::is_same_v) { - builder.create(entryOp.getLoc(), entryOp.getAccPtr(), varPtr, + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), entryOp.getBounds(), entryOp.getDataClause(), /*structured=*/false, /*implicit=*/false, builder.getStringAttr(*entryOp.getName())); @@ -2904,14 +2997,18 @@ static void createDeclareDeallocFunc(mlir::OpBuilder &modBuilder, builder.create( loc, mlir::Value{}, mlir::ValueRange(entryOp.getAccPtr())); - mlir::Value varPtr; if constexpr (std::is_same_v || std::is_same_v) - varPtr = entryOp.getVarPtr(); - builder.create(entryOp.getLoc(), entryOp.getAccPtr(), varPtr, - entryOp.getBounds(), entryOp.getDataClause(), - /*structured=*/false, /*implicit=*/false, - builder.getStringAttr(*entryOp.getName())); + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), + entryOp.getVarPtr(), entryOp.getBounds(), + entryOp.getDataClause(), + /*structured=*/false, /*implicit=*/false, + builder.getStringAttr(*entryOp.getName())); + else + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), + entryOp.getBounds(), entryOp.getDataClause(), + /*structured=*/false, /*implicit=*/false, + builder.getStringAttr(*entryOp.getName())); // Generate the post dealloc function. modBuilder.setInsertionPointAfter(preDeallocOp); diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index eeba87fcd151169ac0f2abdf5ea2b16ffa6dd1b1..c3a570bf15ea0d0816cc8bfe3ec5d12cf94fde41 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -18,6 +18,7 @@ #include "flang/Lower/ConvertVariable.h" #include "flang/Lower/PFTBuilder.h" #include "flang/Lower/StatementContext.h" +#include "flang/Lower/SymbolMap.h" #include "flang/Optimizer/Builder/BoxValue.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/Todo.h" @@ -29,6 +30,7 @@ #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/Transforms/RegionUtils.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Support/CommandLine.h" @@ -605,6 +607,12 @@ public: llvm::SmallVectorImpl &useDeviceSymbols) const; + template + bool + processMotionClauses(Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::StatementContext &stmtCtx, + llvm::SmallVectorImpl &mapOperands); + // Call this method for these clauses that should be supported but are not // implemented yet. It triggers a compilation error if any of the given // clauses is found. @@ -1793,27 +1801,28 @@ bool ClauseProcessor::processMap( std::get(mapClause->v.t).v) { llvm::SmallVector bounds; std::stringstream asFortran; - mlir::Value baseAddr = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::OmpObject, mlir::omp::DataBoundsType, - mlir::omp::DataBoundsOp>( - converter, firOpBuilder, semanticsContext, stmtCtx, ompObject, - clauseLocation, asFortran, bounds, treatIndexAsSection); + Fortran::lower::AddrAndBoundsInfo info = + Fortran::lower::gatherDataOperandAddrAndBounds< + Fortran::parser::OmpObject, mlir::omp::DataBoundsOp, + mlir::omp::DataBoundsType>( + converter, firOpBuilder, semanticsContext, stmtCtx, ompObject, + clauseLocation, asFortran, bounds, treatIndexAsSection); // Explicit map captures are captured ByRef by default, // optimisation passes may alter this to ByCopy or other capture // types to optimise mlir::Value mapOp = createMapInfoOp( - firOpBuilder, clauseLocation, baseAddr, asFortran, bounds, + firOpBuilder, clauseLocation, info.addr, asFortran, bounds, static_cast< std::underlying_type_t>( mapTypeBits), - mlir::omp::VariableCaptureKind::ByRef, baseAddr.getType()); + mlir::omp::VariableCaptureKind::ByRef, info.addr.getType()); mapOperands.push_back(mapOp); if (mapSymTypes) - mapSymTypes->push_back(baseAddr.getType()); + mapSymTypes->push_back(info.addr.getType()); if (mapSymLocs) - mapSymLocs->push_back(baseAddr.getLoc()); + mapSymLocs->push_back(info.addr.getLoc()); if (mapSymbols) mapSymbols->push_back(getOmpObjectSymbol(ompObject)); } @@ -1890,6 +1899,47 @@ bool ClauseProcessor::processUseDevicePtr( }); } +template +bool ClauseProcessor::processMotionClauses( + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::StatementContext &stmtCtx, + llvm::SmallVectorImpl &mapOperands) { + return findRepeatableClause( + [&](const T *motionClause, const Fortran::parser::CharBlock &source) { + mlir::Location clauseLocation = converter.genLocation(source); + fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + + static_assert(std::is_same_v || + std::is_same_v); + + // TODO Support motion modifiers: present, mapper, iterator. + constexpr llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = + std::is_same_v + ? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO + : llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; + + for (const Fortran::parser::OmpObject &ompObject : motionClause->v.v) { + llvm::SmallVector bounds; + std::stringstream asFortran; + Fortran::lower::AddrAndBoundsInfo info = + Fortran::lower::gatherDataOperandAddrAndBounds< + Fortran::parser::OmpObject, mlir::omp::DataBoundsOp, + mlir::omp::DataBoundsType>( + converter, firOpBuilder, semanticsContext, stmtCtx, ompObject, + clauseLocation, asFortran, bounds, treatIndexAsSection); + + mlir::Value mapOp = createMapInfoOp( + firOpBuilder, clauseLocation, info.addr, asFortran, bounds, + static_cast< + std::underlying_type_t>( + mapTypeBits), + mlir::omp::VariableCaptureKind::ByRef, info.addr.getType()); + + mapOperands.push_back(mapOp); + } + }); +} + template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { @@ -2117,21 +2167,16 @@ static void createBodyOfOp( for (const Fortran::semantics::Symbol *arg : args) loopVarTypeSize = std::max(loopVarTypeSize, arg->GetUltimate().size()); mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize); - llvm::SmallVector tiv; - llvm::SmallVector locs; - for (int i = 0; i < (int)args.size(); i++) { - tiv.push_back(loopVarType); - locs.push_back(loc); - } + llvm::SmallVector tiv(args.size(), loopVarType); + llvm::SmallVector locs(args.size(), loc); firOpBuilder.createBlock(&op.getRegion(), {}, tiv, locs); - int argIndex = 0; // The argument is not currently in memory, so make a temporary for the // argument, and store it there, then bind that location to the argument. - for (const Fortran::semantics::Symbol *arg : args) { + for (auto [argIndex, argSymbol] : llvm::enumerate(args)) { mlir::Value indexVal = fir::getBase(op.getRegion().front().getArgument(argIndex)); - storeOp = createAndSetPrivatizedLoopVar(converter, loc, indexVal, arg); - argIndex++; + storeOp = + createAndSetPrivatizedLoopVar(converter, loc, indexVal, argSymbol); } } else { firOpBuilder.createBlock(&op.getRegion()); @@ -2192,14 +2237,15 @@ static void genBodyOfTargetDataOp( firOpBuilder.createBlock(®ion, {}, useDeviceTypes, useDeviceLocs); - unsigned argIndex = 0; - for (const Fortran::semantics::Symbol *sym : useDeviceSymbols) { + for (auto [argIndex, argSymbol] : llvm::enumerate(useDeviceSymbols)) { const mlir::BlockArgument &arg = region.front().getArgument(argIndex); - fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*sym); + fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*argSymbol); if (auto refType = arg.getType().dyn_cast()) { if (fir::isa_builtin_cptr_type(refType.getElementType())) { - converter.bindSymbol(*sym, arg); + converter.bindSymbol(*argSymbol, arg); } else { + // Avoid capture of a reference to a structured binding. + const Fortran::semantics::Symbol *sym = argSymbol; extVal.match( [&](const fir::MutableBoxValue &mbv) { converter.bindSymbol( @@ -2216,7 +2262,6 @@ static void genBodyOfTargetDataOp( TODO(converter.getCurrentLocation(), "use_device clause operand unsupported type"); } - argIndex++; } // Insert dummy instruction to remember the insertion position. The @@ -2418,10 +2463,10 @@ genDataOp(Fortran::lower::AbstractConverter &converter, template static OpTy -genEnterExitDataOp(Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semanticsContext, - mlir::Location currentLocation, - const Fortran::parser::OmpClauseList &clauseList) { +genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semanticsContext, + mlir::Location currentLocation, + const Fortran::parser::OmpClauseList &clauseList) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); Fortran::lower::StatementContext stmtCtx; mlir::Value ifClauseOperand, deviceOperand; @@ -2438,6 +2483,10 @@ genEnterExitDataOp(Fortran::lower::AbstractConverter &converter, directiveName = Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetExitData; directive = llvm::omp::Directive::OMPD_target_exit_data; + } else if constexpr (std::is_same_v) { + directiveName = + Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetUpdate; + directive = llvm::omp::Directive::OMPD_target_update; } else { return nullptr; } @@ -2446,8 +2495,18 @@ genEnterExitDataOp(Fortran::lower::AbstractConverter &converter, cp.processIf(directiveName, ifClauseOperand); cp.processDevice(stmtCtx, deviceOperand); cp.processNowait(nowaitAttr); - cp.processMap(currentLocation, directive, semanticsContext, stmtCtx, - mapOperands); + + if constexpr (std::is_same_v) { + cp.processMotionClauses( + semanticsContext, stmtCtx, mapOperands); + cp.processMotionClauses( + semanticsContext, stmtCtx, mapOperands); + + } else { + cp.processMap(currentLocation, directive, semanticsContext, stmtCtx, + mapOperands); + } + cp.processTODO(currentLocation, directive); @@ -2472,8 +2531,6 @@ static void genBodyOfTargetOp( auto *regionBlock = firOpBuilder.createBlock(®ion, {}, mapSymTypes, mapSymLocs); - unsigned argIndex = 0; - // Clones the `bounds` placing them inside the target region and returns them. auto cloneBound = [&](mlir::Value bound) { if (mlir::isMemoryEffectFree(bound.getDefiningOp())) { @@ -2493,8 +2550,10 @@ static void genBodyOfTargetOp( }; // Bind the symbols to their corresponding block arguments. - for (const Fortran::semantics::Symbol *sym : mapSymbols) { + for (auto [argIndex, argSymbol] : llvm::enumerate(mapSymbols)) { const mlir::BlockArgument &arg = region.getArgument(argIndex); + // Avoid capture of a reference to a structured binding. + const Fortran::semantics::Symbol *sym = argSymbol; fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*sym); extVal.match( [&](const fir::BoxValue &v) { @@ -2529,7 +2588,6 @@ static void genBodyOfTargetOp( TODO(converter.getCurrentLocation(), "target map clause operand unsupported type"); }); - argIndex++; } // Check if cloning the bounds introduced any dependency on the outer region. @@ -2658,20 +2716,20 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(sym); name << sym.name().ToString(); - mlir::Value baseAddr = + Fortran::lower::AddrAndBoundsInfo info = getDataOperandBaseAddr(converter, converter.getFirOpBuilder(), sym, converter.getCurrentLocation()); - if (fir::unwrapRefType(baseAddr.getType()).isa()) + if (fir::unwrapRefType(info.addr.getType()).isa()) bounds = Fortran::lower::genBoundsOpsFromBox( converter.getFirOpBuilder(), converter.getCurrentLocation(), - converter, dataExv, baseAddr); - if (fir::unwrapRefType(baseAddr.getType()).isa()) + converter, dataExv, info); + if (fir::unwrapRefType(info.addr.getType()).isa()) bounds = Fortran::lower::genBaseBoundsOps( converter.getFirOpBuilder(), converter.getCurrentLocation(), - converter, dataExv, baseAddr); + converter, dataExv); llvm::omp::OpenMPOffloadMappingFlags mapFlag = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT; @@ -2850,15 +2908,17 @@ genOmpSimpleStandalone(Fortran::lower::AbstractConverter &converter, genDataOp(converter, eval, semanticsContext, currentLocation, opClauseList); break; case llvm::omp::Directive::OMPD_target_enter_data: - genEnterExitDataOp(converter, semanticsContext, - currentLocation, opClauseList); + genEnterExitUpdateDataOp( + converter, semanticsContext, currentLocation, opClauseList); break; case llvm::omp::Directive::OMPD_target_exit_data: - genEnterExitDataOp(converter, semanticsContext, - currentLocation, opClauseList); + genEnterExitUpdateDataOp( + converter, semanticsContext, currentLocation, opClauseList); break; case llvm::omp::Directive::OMPD_target_update: - TODO(currentLocation, "OMPD_target_update"); + genEnterExitUpdateDataOp( + converter, semanticsContext, currentLocation, opClauseList); + break; case llvm::omp::Directive::OMPD_ordered: TODO(currentLocation, "OMPD_ordered"); } @@ -3388,27 +3448,12 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, } } -//===----------------------------------------------------------------------===// -// Public functions -//===----------------------------------------------------------------------===// - -void Fortran::lower::genOpenMPTerminator(fir::FirOpBuilder &builder, - mlir::Operation *op, - mlir::Location loc) { - if (mlir::isa(op)) - builder.create(loc); - else - builder.create(loc); -} - -void Fortran::lower::genOpenMPConstruct( - Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::pft::Evaluation &eval, - const Fortran::parser::OpenMPConstruct &ompConstruct) { +static void genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenMPConstruct &ompConstruct) { std::visit( - common::visitors{ + Fortran::common::visitors{ [&](const Fortran::parser::OpenMPStandaloneConstruct &standaloneConstruct) { genOMP(converter, eval, semanticsContext, standaloneConstruct); @@ -3449,12 +3494,12 @@ void Fortran::lower::genOpenMPConstruct( ompConstruct.u); } -void Fortran::lower::genOpenMPDeclarativeConstruct( - Fortran::lower::AbstractConverter &converter, - Fortran::lower::pft::Evaluation &eval, - const Fortran::parser::OpenMPDeclarativeConstruct &ompDeclConstruct) { +static void +genOMP(Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenMPDeclarativeConstruct &ompDeclConstruct) { std::visit( - common::visitors{ + Fortran::common::visitors{ [&](const Fortran::parser::OpenMPDeclarativeAllocate &declarativeAllocate) { TODO(converter.getCurrentLocation(), "OpenMPDeclarativeAllocate"); @@ -3487,6 +3532,92 @@ void Fortran::lower::genOpenMPDeclarativeConstruct( ompDeclConstruct.u); } +//===----------------------------------------------------------------------===// +// Public functions +//===----------------------------------------------------------------------===// + +void Fortran::lower::genOpenMPTerminator(fir::FirOpBuilder &builder, + mlir::Operation *op, + mlir::Location loc) { + if (mlir::isa(op)) + builder.create(loc); + else + builder.create(loc); +} + +void Fortran::lower::genOpenMPConstruct( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symTable, + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenMPConstruct &omp) { + + symTable.pushScope(); + genOMP(converter, semanticsContext, eval, omp); + + const Fortran::parser::OpenMPLoopConstruct *ompLoop = + std::get_if(&omp.u); + const Fortran::parser::OpenMPBlockConstruct *ompBlock = + std::get_if(&omp.u); + + // If loop is part of an OpenMP Construct then the OpenMP dialect + // workshare loop operation has already been created. Only the + // body needs to be created here and the do_loop can be skipped. + // Skip the number of collapsed loops, which is 1 when there is a + // no collapse requested. + + Fortran::lower::pft::Evaluation *curEval = &eval; + const Fortran::parser::OmpClauseList *loopOpClauseList = nullptr; + if (ompLoop) { + loopOpClauseList = &std::get( + std::get(ompLoop->t).t); + int64_t collapseValue = Fortran::lower::getCollapseValue(*loopOpClauseList); + + curEval = &curEval->getFirstNestedEvaluation(); + for (int64_t i = 1; i < collapseValue; i++) { + curEval = &*std::next(curEval->getNestedEvaluations().begin()); + } + } + + for (Fortran::lower::pft::Evaluation &e : curEval->getNestedEvaluations()) + converter.genEval(e); + + if (ompLoop) { + genOpenMPReduction(converter, *loopOpClauseList); + } else if (ompBlock) { + const auto &blockStart = + std::get(ompBlock->t); + const auto &blockClauses = + std::get(blockStart.t); + genOpenMPReduction(converter, blockClauses); + } + + symTable.popScope(); +} + +void Fortran::lower::genOpenMPDeclarativeConstruct( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenMPDeclarativeConstruct &omp) { + genOMP(converter, eval, omp); + for (Fortran::lower::pft::Evaluation &e : eval.getNestedEvaluations()) + converter.genEval(e); +} + +void Fortran::lower::genOpenMPSymbolProperties( + Fortran::lower::AbstractConverter &converter, + const Fortran::lower::pft::Variable &var) { + assert(var.hasSymbol() && "Expecting Symbol"); + const Fortran::semantics::Symbol &sym = var.getSymbol(); + + if (sym.test(Fortran::semantics::Symbol::Flag::OmpThreadprivate)) + Fortran::lower::genThreadprivateOp(converter, var); + + if (sym.test(Fortran::semantics::Symbol::Flag::OmpDeclareTarget)) + Fortran::lower::genDeclareTargetIntGlobal(converter, var); +} + int64_t Fortran::lower::getCollapseValue( const Fortran::parser::OmpClauseList &clauseList) { for (const Fortran::parser::OmpClause &clause : clauseList.v) { diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp index 32ed539c775b827c1bec544720017c3adbe60ab8..0e32e2c7d96a772a3f2483cd9ff0591c726d5e32 100644 --- a/flang/lib/Lower/PFTBuilder.cpp +++ b/flang/lib/Lower/PFTBuilder.cpp @@ -149,22 +149,22 @@ public: // Modules IEEE_FEATURES, IEEE_EXCEPTIONS, and IEEE_ARITHMETIC get common // declarations from several __fortran_... support module files. llvm::StringRef modName = toStringRef(modSym.name()); - if (!modName.startswith("ieee_") && !modName.startswith("__fortran_")) + if (!modName.starts_with("ieee_") && !modName.starts_with("__fortran_")) return; llvm::StringRef procName = toStringRef(procSym.name()); - if (!procName.startswith("ieee_")) + if (!procName.starts_with("ieee_")) return; lower::pft::FunctionLikeUnit *proc = evaluationListStack.back()->back().getOwningProcedure(); proc->hasIeeeAccess = true; - if (!procName.startswith("ieee_set_")) + if (!procName.starts_with("ieee_set_")) return; - if (procName.startswith("ieee_set_modes_") || - procName.startswith("ieee_set_status_")) + if (procName.starts_with("ieee_set_modes_") || + procName.starts_with("ieee_set_status_")) proc->mayModifyHaltingMode = proc->mayModifyRoundingMode = true; - else if (procName.startswith("ieee_set_halting_mode_")) + else if (procName.starts_with("ieee_set_halting_mode_")) proc->mayModifyHaltingMode = true; - else if (procName.startswith("ieee_set_rounding_mode_")) + else if (procName.starts_with("ieee_set_rounding_mode_")) proc->mayModifyRoundingMode = true; } @@ -541,15 +541,15 @@ private: /// The transformation is only valid for forward branch targets at the same /// construct nesting level as the IfConstruct. The result must not violate /// construct nesting requirements or contain an EntryStmt. The result - /// is subject to normal un/structured code classification analysis. The - /// result is allowed to violate the F18 Clause 11.1.2.1 prohibition on - /// transfer of control into the interior of a construct block, as that does - /// not compromise correct code generation. When two transformation - /// candidates overlap, at least one must be disallowed. In such cases, - /// the current heuristic favors simple code generation, which happens to - /// favor later candidates over earlier candidates. That choice is probably - /// not significant, but could be changed. - /// + /// is subject to normal un/structured code classification analysis. Except + /// for a branch to the EndIfStmt, the result is allowed to violate the F18 + /// Clause 11.1.2.1 prohibition on transfer of control into the interior of + /// a construct block, as that does not compromise correct code generation. + /// When two transformation candidates overlap, at least one must be + /// disallowed. In such cases, the current heuristic favors simple code + /// generation, which happens to favor later candidates over earlier + /// candidates. That choice is probably not significant, but could be + /// changed. void rewriteIfGotos() { auto &evaluationList = *evaluationListStack.back(); if (!evaluationList.size()) @@ -616,7 +616,8 @@ private: if (eval.isA() && eval.evaluationList->size() == 3) { const auto bodyEval = std::next(eval.evaluationList->begin()); if (const auto *gotoStmt = bodyEval->getIf()) { - ifCandidateStack.push_back({it, gotoStmt->v}); + if (!bodyEval->lexicalSuccessor->label) + ifCandidateStack.push_back({it, gotoStmt->v}); } else if (doStmt) { if (const auto *cycleStmt = bodyEval->getIf()) { std::string cycleName = getConstructName(*cycleStmt); diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp index 8855cab8b5174ea8ef7c70ee6f084a7090372620..e7695929623f6ddb8f284733106c3f4435f2579c 100644 --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -137,6 +137,12 @@ void Fortran::lower::genFailImageStatement( genUnreachable(builder, loc); } +void Fortran::lower::genNotifyWaitStatement( + Fortran::lower::AbstractConverter &converter, + const Fortran::parser::NotifyWaitStmt &) { + TODO(converter.getCurrentLocation(), "coarray: NOTIFY WAIT runtime"); +} + void Fortran::lower::genEventPostStatement( Fortran::lower::AbstractConverter &converter, const Fortran::parser::EventPostStmt &) { diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp index 17efa45b8667d383762d90414c5e17d5726af8e2..94f723b4bae7036a518154d7d45db46cc0dd2f09 100644 --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -935,7 +935,7 @@ hlfir::translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder, std::pair> hlfir::convertToValue(mlir::Location loc, fir::FirOpBuilder &builder, - const hlfir::Entity &entity) { + hlfir::Entity entity) { // Load scalar references to integer, logical, real, or complex value // to an mlir value, dereference allocatable and pointers, and get rid // of fir.box that are not needed or create a copy into contiguous memory. @@ -957,7 +957,12 @@ static fir::ExtendedValue placeTrivialInMemory(mlir::Location loc, std::pair> hlfir::convertToBox(mlir::Location loc, fir::FirOpBuilder &builder, - const hlfir::Entity &entity, mlir::Type targetType) { + hlfir::Entity entity, mlir::Type targetType) { + // fir::factory::createBoxValue is not meant to deal with procedures. + // Dereference procedure pointers here. + if (entity.isProcedurePointer()) + entity = hlfir::derefPointersAndAllocatables(loc, builder, entity); + auto [exv, cleanup] = translateToExtendedValue(loc, builder, entity); // Procedure entities should not go through createBoxValue that embox // object entities. Return the fir.boxproc directly. @@ -972,7 +977,7 @@ hlfir::convertToBox(mlir::Location loc, fir::FirOpBuilder &builder, std::pair> hlfir::convertToAddress(mlir::Location loc, fir::FirOpBuilder &builder, - const hlfir::Entity &entity, mlir::Type targetType) { + hlfir::Entity entity, mlir::Type targetType) { hlfir::Entity derefedEntity = hlfir::derefPointersAndAllocatables(loc, builder, entity); auto [exv, cleanup] = diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 45c75fc5dd28bc0534daefff90fd721fde6dee92..c8057fbdd475afcec1e0a8655133ea303fbffcad 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -165,6 +165,10 @@ static constexpr IntrinsicHandler handlers[]{ {"fptr", asInquired}, {"shape", asAddr, handleDynamicOptional}}}, /*isElemental=*/false}, + {"c_f_procpointer", + &I::genCFProcPointer, + {{{"cptr", asValue}, {"fptr", asInquired}}}, + /*isElemental=*/false}, {"c_funloc", &I::genCFunLoc, {{{"x", asBox}}}, /*isElemental=*/false}, {"c_loc", &I::genCLoc, {{{"x", asBox}}}, /*isElemental=*/false}, {"ceiling", &I::genCeiling}, @@ -1418,13 +1422,13 @@ mlir::Value toValue(const fir::ExtendedValue &val, fir::FirOpBuilder &builder, //===----------------------------------------------------------------------===// static bool isIntrinsicModuleProcedure(llvm::StringRef name) { - return name.startswith("c_") || name.startswith("compiler_") || - name.startswith("ieee_") || name.startswith("__ppc_"); + return name.starts_with("c_") || name.starts_with("compiler_") || + name.starts_with("ieee_") || name.starts_with("__ppc_"); } static bool isCoarrayIntrinsic(llvm::StringRef name) { - return name.startswith("atomic_") || name.startswith("co_") || - name.contains("image") || name.endswith("cobound") || + return name.starts_with("atomic_") || name.starts_with("co_") || + name.contains("image") || name.ends_with("cobound") || name.equals("team_number"); } @@ -1433,7 +1437,7 @@ static bool isCoarrayIntrinsic(llvm::StringRef name) { /// {_[ail]?[0-9]+}*, such as _1 or _a4. llvm::StringRef genericName(llvm::StringRef specificName) { const std::string builtin = "__builtin_"; - llvm::StringRef name = specificName.startswith(builtin) + llvm::StringRef name = specificName.starts_with(builtin) ? specificName.drop_front(builtin.size()) : specificName; size_t size = name.size(); @@ -2134,6 +2138,33 @@ fir::ExtendedValue IntrinsicLibrary::genAssociated(mlir::Type resultType, llvm::ArrayRef args) { assert(args.size() == 2); + if (fir::isBoxProcAddressType(fir::getBase(args[0]).getType())) { + mlir::Value pointerBoxProc = + builder.create(loc, fir::getBase(args[0])); + mlir::Value pointerTarget = + builder.create(loc, pointerBoxProc); + if (isStaticallyAbsent(args[1])) + return builder.genIsNotNullAddr(loc, pointerTarget); + mlir::Value target = fir::getBase(args[1]); + if (fir::isBoxProcAddressType(target.getType())) + target = builder.create(loc, target); + if (target.getType().isa()) + target = builder.create(loc, target); + mlir::Type intPtrTy = builder.getIntPtrType(); + mlir::Value pointerInt = + builder.createConvert(loc, intPtrTy, pointerTarget); + mlir::Value targetInt = builder.createConvert(loc, intPtrTy, target); + mlir::Value sameTarget = builder.create( + loc, mlir::arith::CmpIPredicate::eq, pointerInt, targetInt); + mlir::Value zero = builder.createIntegerConstant(loc, intPtrTy, 0); + mlir::Value notNull = builder.create( + loc, mlir::arith::CmpIPredicate::ne, zero, pointerInt); + // The not notNull test covers the following two cases: + // - TARGET is a procedure that is OPTIONAL and absent at runtime. + // - TARGET is a procedure pointer that is NULL. + // In both cases, ASSOCIATED should be false if POINTER is NULL. + return builder.create(loc, sameTarget, notNull); + } auto *pointer = args[0].match([&](const fir::MutableBoxValue &x) { return &x; }, [&](const auto &) -> const fir::MutableBoxValue * { @@ -2498,6 +2529,22 @@ void IntrinsicLibrary::genCFPointer(llvm::ArrayRef args) { /*lbounds=*/mlir::ValueRange{}); } +// C_F_PROCPOINTER +void IntrinsicLibrary::genCFProcPointer( + llvm::ArrayRef args) { + assert(args.size() == 2); + mlir::Value cptr = + fir::factory::genCPtrOrCFunptrValue(builder, loc, fir::getBase(args[0])); + mlir::Value fptr = fir::getBase(args[1]); + auto boxProcType = + mlir::cast(fir::unwrapRefType(fptr.getType())); + mlir::Value cptrCast = + builder.createConvert(loc, boxProcType.getEleTy(), cptr); + mlir::Value cptrBox = + builder.create(loc, boxProcType, cptrCast); + builder.create(loc, cptrBox, fptr); +} + // C_FUNLOC fir::ExtendedValue IntrinsicLibrary::genCFunLoc(mlir::Type resultType, diff --git a/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp b/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp index 524f0e3135ac30bab575edb104590c2747c35db4..d4cc2b5732e4cabd9ddba50de4aa68bb47807e31 100644 --- a/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp +++ b/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp @@ -19,6 +19,7 @@ #include "mlir/IR/PatternMatch.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" +#include "llvm/ADT/MapVector.h" namespace fir { #define GEN_PASS_DEF_BOXEDPROCEDUREPASS @@ -81,7 +82,7 @@ public: visitedTypes.pop_back(); return result; } - if (auto boxTy = ty.dyn_cast()) + if (auto boxTy = ty.dyn_cast()) return needsConversion(boxTy.getEleTy()); if (isa_ref_type(ty)) return needsConversion(unwrapRefType(ty)); @@ -117,8 +118,14 @@ public: }); addConversion( [&](HeapType ty) { return HeapType::get(convertType(ty.getEleTy())); }); + addConversion([&](fir::LLVMPointerType ty) { + return fir::LLVMPointerType::get(convertType(ty.getEleTy())); + }); addConversion( [&](BoxType ty) { return BoxType::get(convertType(ty.getEleTy())); }); + addConversion([&](ClassType ty) { + return ClassType::get(convertType(ty.getEleTy())); + }); addConversion([&](SequenceType ty) { // TODO: add ty.getLayoutMap() as needed. return SequenceType::get(ty.getShape(), convertType(ty.getEleTy())); @@ -126,10 +133,13 @@ public: addConversion([&](RecordType ty) -> mlir::Type { if (!needsConversion(ty)) return ty; + if (auto converted = typeInConversion.lookup(ty)) + return converted; auto rec = RecordType::get(ty.getContext(), ty.getName().str() + boxprocSuffix.str()); if (rec.isFinalized()) return rec; + auto it = typeInConversion.try_emplace(ty, rec); std::vector ps = ty.getLenParamList(); std::vector cs; for (auto t : ty.getTypeList()) { @@ -139,6 +149,7 @@ public: cs.emplace_back(t.first, t.second); } rec.finalize(ps, cs); + typeInConversion.erase(it.first); return rec; }); addArgumentMaterialization(materializeProcedure); @@ -159,6 +170,7 @@ public: private: llvm::SmallVector visitedTypes; + llvm::SmallMapVector typeInConversion; mlir::Location loc; }; @@ -193,7 +205,8 @@ public: getModule().walk([&](mlir::Operation *op) { typeConverter.setLocation(op->getLoc()); if (auto addr = mlir::dyn_cast(op)) { - auto ty = addr.getVal().getType(); + mlir::Type ty = addr.getVal().getType(); + mlir::Type resTy = addr.getResult().getType(); if (typeConverter.needsConversion(ty) || ty.isa()) { // Rewrite all `fir.box_addr` ops on values of type `!fir.boxproc` @@ -201,6 +214,10 @@ public: rewriter.setInsertionPoint(addr); rewriter.replaceOpWithNewOp( addr, typeConverter.convertType(addr.getType()), addr.getVal()); + } else if (typeConverter.needsConversion(resTy)) { + rewriter.startRootUpdate(op); + op->getResult(0).setType(typeConverter.convertType(resTy)); + rewriter.finalizeRootUpdate(op); } } else if (auto func = mlir::dyn_cast(op)) { mlir::FunctionType ty = func.getFunctionType(); @@ -223,7 +240,8 @@ public: } else if (auto embox = mlir::dyn_cast(op)) { // Rewrite all `fir.emboxproc` ops to either `fir.convert` or a thunk // as required. - mlir::Type toTy = embox.getType().cast().getEleTy(); + mlir::Type toTy = typeConverter.convertType( + embox.getType().cast().getEleTy()); rewriter.setInsertionPoint(embox); if (embox.getHost()) { // Create the thunk. diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index 3cd0e66fc7a1d93fa21635de925ed8d320af8df7..ff3f9c4d6e7786b8d05eba091eb347f2fcaf8342 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -589,6 +589,21 @@ struct TargetX86_64 : public GenericTarget { Hi = SSE; } + /// When \p recTy is a one field record type that can be passed + /// like the field on its own, returns the field type. Returns + /// a null type otherwise. + mlir::Type passAsFieldIfOneFieldStruct(fir::RecordType recTy) const { + auto typeList = recTy.getTypeList(); + if (typeList.size() != 1) + return {}; + mlir::Type fieldType = typeList[0].second; + if (mlir::isa(fieldType)) + return fieldType; + // Complex field that needs to be split, or array. + return {}; + } + /// Marshal a derived type passed by value like a C struct. CodeGenSpecifics::Marshalling structArgumentType(mlir::Location loc, fir::RecordType recTy, @@ -617,7 +632,14 @@ struct TargetX86_64 : public GenericTarget { if (!hasEnoughRegisters(loc, neededIntRegisters, neededSSERegisters, previousArguments)) return passOnTheStack(loc, recTy); - // TODO, marshal the struct into registers. + + if (auto fieldType = passAsFieldIfOneFieldStruct(recTy)) { + CodeGenSpecifics::Marshalling marshal; + marshal.emplace_back(fieldType, AT{}); + return marshal; + } + // TODO, marshal the struct with several components, or with a single + // complex, array, or derived type component into registers. TODO(loc, "passing BIND(C), VALUE derived type in registers on X86-64"); } diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp index 277f3e447ed164c533a0f3c36befefab4675e85f..2f5c8cc0071ae178235e27d79ba88863c7910e39 100644 --- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -79,6 +79,7 @@ public: TargetRewrite(const fir::TargetRewriteOptions &options) { noCharacterConversion = options.noCharacterConversion; noComplexConversion = options.noComplexConversion; + noStructConversion = options.noStructConversion; } void runOnOperation() override final { @@ -252,6 +253,11 @@ public: fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, llvm::SmallVectorImpl &newOpers, mlir::Value &savedStackPtr) { + if (noStructConversion) { + newInTyAndAttrs.push_back(fir::CodeGenSpecifics::getTypeAndAttr(recTy)); + newOpers.push_back(oper); + return; + } auto structArgs = specifics->structArgumentType(loc, recTy, newInTyAndAttrs); if (structArgs.size() != 1) @@ -522,6 +528,10 @@ public: void lowerStructSignatureArg(mlir::Location loc, fir::RecordType recTy, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs) { + if (noStructConversion) { + newInTyAndAttrs.push_back(fir::CodeGenSpecifics::getTypeAndAttr(recTy)); + return; + } auto structArgs = specifics->structArgumentType(loc, recTy, newInTyAndAttrs); newInTyAndAttrs.insert(newInTyAndAttrs.end(), structArgs.begin(), @@ -645,7 +655,7 @@ public: !noCharacterConversion) || (fir::isa_complex(ty) && !noComplexConversion) || (ty.isa() && hasCCallingConv) || - ty.isa()) { + (ty.isa() && !noStructConversion)) { LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n"); return false; } @@ -1128,6 +1138,10 @@ public: void doStructArg(mlir::func::FuncOp func, fir::RecordType recTy, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, FIXUPS &fixups) { + if (noStructConversion) { + newInTyAndAttrs.push_back(fir::CodeGenSpecifics::getTypeAndAttr(recTy)); + return; + } auto structArgs = specifics->structArgumentType(func.getLoc(), recTy, newInTyAndAttrs); createFuncOpArgFixups(func, newInTyAndAttrs, structArgs, fixups); diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp index 209c586411f410c7c5717d401dca4216db7e4ddd..62a8e4750dc8c94b2bc90151e06dbc8480172e81 100644 --- a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp +++ b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp @@ -20,6 +20,7 @@ #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Dialect/Support/FIRContext.h" #include "flang/Optimizer/Dialect/Support/KindMapping.h" +#include "flang/Optimizer/Support/InternalNames.h" #include "mlir/Conversion/LLVMCommon/TypeConverter.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Debug.h" @@ -164,7 +165,7 @@ mlir::Type LLVMTypeConverter::indexType() const { // fir.type --> llvm<"%name = { ty... }"> std::optional LLVMTypeConverter::convertRecordType( fir::RecordType derived, llvm::SmallVectorImpl &results) { - auto name = derived.getName(); + auto name = fir::NameUniquer::dropTypeConversionMarkers(derived.getName()); auto st = mlir::LLVM::LLVMStructType::getIdentified(&getContext(), name); auto &callStack = getCurrentThreadRecursiveStack(); diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index ab1e9c0ec7adc858530f3d1dbb5cc2f880cfd7a0..6d62e470706e5306749382cc4062bb148bc1f56f 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -625,11 +625,13 @@ void fir::BoxAddrOp::build(mlir::OpBuilder &builder, mlir::OpFoldResult fir::BoxAddrOp::fold(FoldAdaptor adaptor) { if (auto *v = getVal().getDefiningOp()) { if (auto box = mlir::dyn_cast(v)) { - if (!box.getSlice()) // Fold only if not sliced + // Fold only if not sliced + if (!box.getSlice() && box.getMemref().getType() == getType()) return box.getMemref(); } if (auto box = mlir::dyn_cast(v)) - return box.getMemref(); + if (box.getMemref().getType() == getType()) + return box.getMemref(); } return {}; } diff --git a/flang/lib/Optimizer/Dialect/Support/KindMapping.cpp b/flang/lib/Optimizer/Dialect/Support/KindMapping.cpp index c71e3939dc31d28b0704d230fb66d346e18b7560..bcb112186aeefa7af868dda11e1b0e60e64ad269 100644 --- a/flang/lib/Optimizer/Dialect/Support/KindMapping.cpp +++ b/flang/lib/Optimizer/Dialect/Support/KindMapping.cpp @@ -180,7 +180,7 @@ static MatchResult parseInt(unsigned &result, const char *&ptr, static mlir::LogicalResult matchString(const char *&ptr, const char *endPtr, llvm::StringRef literal) { llvm::StringRef s(ptr, endPtr - ptr); - if (s.startswith(literal)) { + if (s.starts_with(literal)) { ptr += literal.size(); return mlir::success(); } diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp index 46eee8acac24b9ff5cf78d05898ea42d4664cf92..439d106d0bfed44ef50deae91e82f82600a42ba6 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -864,17 +864,15 @@ void hlfir::MinvalOp::getEffects( // MinlocOp //===----------------------------------------------------------------------===// -mlir::LogicalResult hlfir::MinlocOp::verify() { - mlir::Operation *op = getOperation(); +template +static mlir::LogicalResult +verifyResultForMinMaxLoc(NumericalReductionOp reductionOp) { + mlir::Operation *op = reductionOp->getOperation(); auto results = op->getResultTypes(); assert(results.size() == 1); - auto res = verifyArrayAndMaskForReductionOp(this); - if (failed(res)) - return res; - - mlir::Value array = getArray(); - mlir::Value dim = getDim(); + mlir::Value array = reductionOp->getArray(); + mlir::Value dim = reductionOp->getDim(); fir::SequenceType arrayTy = hlfir::getFortranElementOrSequenceType(array.getType()) .cast(); @@ -883,28 +881,37 @@ mlir::LogicalResult hlfir::MinlocOp::verify() { mlir::Type resultType = results[0]; if (dim && arrayShape.size() == 1) { if (!fir::isa_integer(resultType)) - return emitOpError("result must be scalar integer"); + return reductionOp->emitOpError("result must be scalar integer"); } else if (auto resultExpr = mlir::dyn_cast_or_null(resultType)) { if (!resultExpr.isArray()) - return emitOpError("result must be an array"); + return reductionOp->emitOpError("result must be an array"); if (!fir::isa_integer(resultExpr.getEleTy())) - return emitOpError("result must have integer elements"); + return reductionOp->emitOpError("result must have integer elements"); llvm::ArrayRef resultShape = resultExpr.getShape(); // With dim the result has rank n-1 if (dim && resultShape.size() != (arrayShape.size() - 1)) - return emitOpError("result rank must be one less than ARRAY"); + return reductionOp->emitOpError( + "result rank must be one less than ARRAY"); // With dim the result has rank n if (!dim && resultShape.size() != 1) - return emitOpError("result rank must be 1"); + return reductionOp->emitOpError("result rank must be 1"); } else { - return emitOpError("result must be of numerical expr type"); + return reductionOp->emitOpError("result must be of numerical expr type"); } return mlir::success(); } +mlir::LogicalResult hlfir::MinlocOp::verify() { + auto res = verifyArrayAndMaskForReductionOp(this); + if (failed(res)) + return res; + + return verifyResultForMinMaxLoc(this); +} + void hlfir::MinlocOp::getEffects( llvm::SmallVectorImpl< mlir::SideEffects::EffectInstance> @@ -912,6 +919,25 @@ void hlfir::MinlocOp::getEffects( getIntrinsicEffects(getOperation(), effects); } +//===----------------------------------------------------------------------===// +// MaxlocOp +//===----------------------------------------------------------------------===// + +mlir::LogicalResult hlfir::MaxlocOp::verify() { + auto res = verifyArrayAndMaskForReductionOp(this); + if (failed(res)) + return res; + + return verifyResultForMinMaxLoc(this); +} + +void hlfir::MaxlocOp::getEffects( + llvm::SmallVectorImpl< + mlir::SideEffects::EffectInstance> + &effects) { + getIntrinsicEffects(getOperation(), effects); +} + //===----------------------------------------------------------------------===// // SetLengthOp //===----------------------------------------------------------------------===// diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp index bfebe26fe1d532eeb851b11f35d8ec5ea058b40b..314e4264c17e8333471562d1e7b8d3c9f214427a 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp @@ -181,6 +181,14 @@ protected: } }; +// Given an integer or array of integer type, calculate the Kind parameter from +// the width for use in runtime intrinsic calls. +static unsigned getKindForType(mlir::Type ty) { + mlir::Type eltty = hlfir::getFortranElementType(ty); + unsigned width = eltty.cast().getWidth(); + return width / 8; +} + template class HlfirReductionIntrinsicConversion : public HlfirIntrinsicConversion { using HlfirIntrinsicConversion::HlfirIntrinsicConversion; @@ -208,10 +216,8 @@ protected: inArgs.push_back({operation.getArray(), operation.getArray().getType()}); inArgs.push_back({operation.getDim(), i32}); inArgs.push_back({operation.getMask(), logicalType}); - mlir::Type T = hlfir::getFortranElementType(operation.getType()); - unsigned width = T.cast().getWidth(); - mlir::Value kind = - builder.createIntegerConstant(operation->getLoc(), i32, width / 8); + mlir::Value kind = builder.createIntegerConstant( + operation->getLoc(), i32, getKindForType(operation.getType())); inArgs.push_back({kind, i32}); inArgs.push_back({operation.getBack(), i32}); auto *argLowering = fir::getIntrinsicArgumentLowering(opName); @@ -243,6 +249,8 @@ public: opName = "minval"; } else if constexpr (std::is_same_v) { opName = "minloc"; + } else if constexpr (std::is_same_v) { + opName = "maxloc"; } else if constexpr (std::is_same_v) { opName = "any"; } else if constexpr (std::is_same_v) { @@ -265,7 +273,8 @@ public: std::is_same_v || std::is_same_v) { args = buildNumericalArgs(operation, i32, logicalType, rewriter, opName); - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v || + std::is_same_v) { args = buildMinMaxLocArgs(operation, i32, logicalType, rewriter, opName, builder); } else { @@ -293,6 +302,8 @@ using MinvalOpConversion = HlfirReductionIntrinsicConversion; using MinlocOpConversion = HlfirReductionIntrinsicConversion; +using MaxlocOpConversion = HlfirReductionIntrinsicConversion; + using AnyOpConversion = HlfirReductionIntrinsicConversion; using AllOpConversion = HlfirReductionIntrinsicConversion; @@ -313,7 +324,9 @@ struct CountOpConversion : public HlfirIntrinsicConversion { llvm::SmallVector inArgs; inArgs.push_back({count.getMask(), logicalType}); inArgs.push_back({count.getDim(), i32}); - inArgs.push_back({count.getKind(), i32}); + mlir::Value kind = builder.createIntegerConstant( + count->getLoc(), i32, getKindForType(count.getType())); + inArgs.push_back({kind, i32}); auto *argLowering = fir::getIntrinsicArgumentLowering("count"); llvm::SmallVector args = @@ -465,12 +478,12 @@ public: mlir::ModuleOp module = this->getOperation(); mlir::MLIRContext *context = &getContext(); mlir::RewritePatternSet patterns(context); - patterns.insert( - context); + patterns + .insert(context); mlir::ConversionTarget target(*context); target.addLegalDialect(); + hlfir::MaxvalOp, hlfir::MinvalOp, hlfir::MinlocOp, + hlfir::MaxlocOp>(); target.markUnknownOpDynamicallyLegal( [](mlir::Operation *) { return true; }); if (mlir::failed( diff --git a/flang/lib/Optimizer/Support/InternalNames.cpp b/flang/lib/Optimizer/Support/InternalNames.cpp index 6138c1f425d62cdc4de1558d7cdef8411c4b6827..65046ea30252ecb740adac04936a42fd196496d3 100644 --- a/flang/lib/Optimizer/Support/InternalNames.cpp +++ b/flang/lib/Optimizer/Support/InternalNames.cpp @@ -240,7 +240,8 @@ llvm::StringRef fir::NameUniquer::doProgramEntry() { std::pair fir::NameUniquer::deconstruct(llvm::StringRef uniq) { - if (uniq.startswith("_Q")) { + uniq = fir::NameUniquer::dropTypeConversionMarkers(uniq); + if (uniq.starts_with("_Q")) { llvm::SmallVector modules; llvm::SmallVector procs; std::int64_t blockId = 0; @@ -353,8 +354,8 @@ mangleTypeDescriptorKinds(llvm::ArrayRef kinds) { static std::string getDerivedTypeObjectName(llvm::StringRef mangledTypeName, const llvm::StringRef separator) { - if (mangledTypeName.ends_with(boxprocSuffix)) - mangledTypeName = mangledTypeName.drop_back(boxprocSuffix.size()); + mangledTypeName = + fir::NameUniquer::dropTypeConversionMarkers(mangledTypeName); auto result = fir::NameUniquer::deconstruct(mangledTypeName); if (result.first != fir::NameUniquer::NameKind::DERIVED_TYPE) return ""; @@ -379,3 +380,10 @@ std::string fir::NameUniquer::getTypeDescriptorBindingTableName( llvm::StringRef mangledTypeName) { return getDerivedTypeObjectName(mangledTypeName, bindingTableSeparator); } + +llvm::StringRef +fir::NameUniquer::dropTypeConversionMarkers(llvm::StringRef mangledTypeName) { + if (mangledTypeName.ends_with(boxprocSuffix)) + return mangledTypeName.drop_back(boxprocSuffix.size()); + return mangledTypeName; +} diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt index 03b67104a93b575e5ef4eddc9a5e2cd75c183a1d..fc067ad3585395549808ce02d07f1ed756ea9424 100644 --- a/flang/lib/Optimizer/Transforms/CMakeLists.txt +++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt @@ -20,6 +20,7 @@ add_flang_library(FIRTransforms OMPFunctionFiltering.cpp OMPMarkDeclareTarget.cpp VScaleAttr.cpp + FunctionAttr.cpp DEPENDS FIRDialect diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55b908ba5d8613981b1779c2cb0870be07dda076 --- /dev/null +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -0,0 +1,62 @@ +//===- FunctionAttr.cpp ---------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +/// \file +/// This is a generic pass for adding attributes to functions. +//===----------------------------------------------------------------------===// +#include "flang/Optimizer/Transforms/Passes.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" + +namespace fir { +#define GEN_PASS_DECL_FUNCTIONATTR +#define GEN_PASS_DEF_FUNCTIONATTR +#include "flang/Optimizer/Transforms/Passes.h.inc" +} // namespace fir + +#define DEBUG_TYPE "func-attr" + +namespace { + +class FunctionAttrPass : public fir::impl::FunctionAttrBase { +public: + FunctionAttrPass(const fir::FunctionAttrOptions &options) { + framePointerKind = options.framePointerKind; + } + FunctionAttrPass() {} + void runOnOperation() override; +}; + +} // namespace + +void FunctionAttrPass::runOnOperation() { + LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n"); + mlir::func::FuncOp func = getOperation(); + + LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n"); + + mlir::MLIRContext *context = &getContext(); + if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None) + func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( + context, framePointerKind)); + + LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); +} + +std::unique_ptr +fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { + FunctionAttrOptions opts; + // Frame pointer + opts.framePointerKind = functionAttr.framePointerKind; + + return std::make_unique(opts); +} + +std::unique_ptr fir::createFunctionAttrPass() { + return std::make_unique(); +} diff --git a/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp b/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp index 3eddb9e61ae3b3df4aad127678795b2eff8bc03c..f5ddcbbaecd21a1a36de0b657510d326c4c7bb17 100644 --- a/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp +++ b/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp @@ -99,8 +99,8 @@ private: void simplifyLogicalDim1Reduction(fir::CallOp call, const fir::KindMapping &kindMap, GenReductionBodyTy genBodyFunc); - void simplifyMinlocReduction(fir::CallOp call, - const fir::KindMapping &kindMap); + void simplifyMinMaxlocReduction(fir::CallOp call, + const fir::KindMapping &kindMap, bool isMax); void simplifyReductionBody(fir::CallOp call, const fir::KindMapping &kindMap, GenReductionBodyTy genBodyFunc, fir::FirOpBuilder &builder, @@ -353,16 +353,15 @@ genReductionLoop(fir::FirOpBuilder &builder, mlir::func::FuncOp &funcOp, // Return the reduction value from the function. builder.create(loc, results[resultIndex]); } -using MinlocBodyOpGeneratorTy = llvm::function_ref &)>; -static void -genMinlocReductionLoop(fir::FirOpBuilder &builder, mlir::func::FuncOp &funcOp, - InitValGeneratorTy initVal, - MinlocBodyOpGeneratorTy genBody, unsigned rank, - mlir::Type elementType, mlir::Location loc, bool hasMask, - mlir::Type maskElemType, mlir::Value resultArr) { +static void genMinMaxlocReductionLoop( + fir::FirOpBuilder &builder, mlir::func::FuncOp &funcOp, + InitValGeneratorTy initVal, MinMaxlocBodyOpGeneratorTy genBody, + unsigned rank, mlir::Type elementType, mlir::Location loc, bool hasMask, + mlir::Type maskElemType, mlir::Value resultArr) { mlir::IndexType idxTy = builder.getIndexType(); @@ -751,21 +750,24 @@ static mlir::FunctionType genRuntimeMinlocType(fir::FirOpBuilder &builder, {boxRefType, boxType, boxType}, {}); } -static void genRuntimeMinlocBody(fir::FirOpBuilder &builder, - mlir::func::FuncOp &funcOp, unsigned rank, - int maskRank, mlir::Type elementType, - mlir::Type maskElemType, - mlir::Type resultElemTy) { - auto init = [](fir::FirOpBuilder builder, mlir::Location loc, - mlir::Type elementType) { +static void genRuntimeMinMaxlocBody(fir::FirOpBuilder &builder, + mlir::func::FuncOp &funcOp, bool isMax, + unsigned rank, int maskRank, + mlir::Type elementType, + mlir::Type maskElemType, + mlir::Type resultElemTy) { + auto init = [isMax](fir::FirOpBuilder builder, mlir::Location loc, + mlir::Type elementType) { if (auto ty = elementType.dyn_cast()) { const llvm::fltSemantics &sem = ty.getFloatSemantics(); return builder.createRealConstant( - loc, elementType, llvm::APFloat::getLargest(sem, /*Negative=*/false)); + loc, elementType, llvm::APFloat::getLargest(sem, /*Negative=*/isMax)); } unsigned bits = elementType.getIntOrFloatBitWidth(); - int64_t maxInt = llvm::APInt::getSignedMaxValue(bits).getSExtValue(); - return builder.createIntegerConstant(loc, elementType, maxInt); + int64_t initValue = (isMax ? llvm::APInt::getSignedMinValue(bits) + : llvm::APInt::getSignedMaxValue(bits)) + .getSExtValue(); + return builder.createIntegerConstant(loc, elementType, initValue); }; mlir::Location loc = mlir::UnknownLoc::get(builder.getContext()); @@ -797,18 +799,24 @@ static void genRuntimeMinlocBody(fir::FirOpBuilder &builder, } auto genBodyOp = - [&rank, &resultArr]( - fir::FirOpBuilder builder, mlir::Location loc, mlir::Type elementType, - mlir::Value elem1, mlir::Value elem2, - llvm::SmallVector indices) + [&rank, &resultArr, + isMax](fir::FirOpBuilder builder, mlir::Location loc, + mlir::Type elementType, mlir::Value elem1, mlir::Value elem2, + llvm::SmallVector indices) -> mlir::Value { mlir::Value cmp; if (elementType.isa()) { cmp = builder.create( - loc, mlir::arith::CmpFPredicate::OLT, elem1, elem2); + loc, + isMax ? mlir::arith::CmpFPredicate::OGT + : mlir::arith::CmpFPredicate::OLT, + elem1, elem2); } else if (elementType.isa()) { cmp = builder.create( - loc, mlir::arith::CmpIPredicate::slt, elem1, elem2); + loc, + isMax ? mlir::arith::CmpIPredicate::sgt + : mlir::arith::CmpIPredicate::slt, + elem1, elem2); } else { llvm_unreachable("unsupported type"); } @@ -875,9 +883,8 @@ static void genRuntimeMinlocBody(fir::FirOpBuilder &builder, // bit of a hack - maskRank is set to -1 for absent mask arg, so don't // generate high level mask or element by element mask. bool hasMask = maskRank > 0; - - genMinlocReductionLoop(builder, funcOp, init, genBodyOp, rank, elementType, - loc, hasMask, maskElemType, resultArr); + genMinMaxlocReductionLoop(builder, funcOp, init, genBodyOp, rank, elementType, + loc, hasMask, maskElemType, resultArr); } /// Generate function type for the simplified version of RTNAME(DotProduct) @@ -1150,16 +1157,19 @@ void SimplifyIntrinsicsPass::simplifyLogicalDim1Reduction( intElementType); } -void SimplifyIntrinsicsPass::simplifyMinlocReduction( - fir::CallOp call, const fir::KindMapping &kindMap) { +void SimplifyIntrinsicsPass::simplifyMinMaxlocReduction( + fir::CallOp call, const fir::KindMapping &kindMap, bool isMax) { mlir::Operation::operand_range args = call.getArgs(); - mlir::Value back = args[6]; + mlir::SymbolRefAttr callee = call.getCalleeAttr(); + mlir::StringRef funcNameBase = callee.getLeafReference().getValue(); + bool isDim = funcNameBase.ends_with("Dim"); + mlir::Value back = args[isDim ? 7 : 6]; if (isTrueOrNotConstant(back)) return; - mlir::Value mask = args[5]; + mlir::Value mask = args[isDim ? 6 : 5]; mlir::Value maskDef = findMaskDef(mask); // maskDef is set to NULL when the defining op is not one we accept. @@ -1168,10 +1178,8 @@ void SimplifyIntrinsicsPass::simplifyMinlocReduction( if (maskDef == NULL) return; - mlir::SymbolRefAttr callee = call.getCalleeAttr(); - mlir::StringRef funcNameBase = callee.getLeafReference().getValue(); unsigned rank = getDimCount(args[1]); - if (funcNameBase.ends_with("Dim") || !(rank > 0)) + if ((isDim && rank != 1) || !(rank > 0)) return; fir::FirOpBuilder builder{getSimplificationBuilder(call, kindMap)}; @@ -1212,22 +1220,24 @@ void SimplifyIntrinsicsPass::simplifyMinlocReduction( llvm::raw_string_ostream nameOS(funcName); outType.print(nameOS); + if (isDim) + nameOS << '_' << inputType; nameOS << '_' << fmfString; auto typeGenerator = [rank](fir::FirOpBuilder &builder) { return genRuntimeMinlocType(builder, rank); }; - auto bodyGenerator = [rank, maskRank, inputType, logicalElemType, - outType](fir::FirOpBuilder &builder, - mlir::func::FuncOp &funcOp) { - genRuntimeMinlocBody(builder, funcOp, rank, maskRank, inputType, - logicalElemType, outType); + auto bodyGenerator = [rank, maskRank, inputType, logicalElemType, outType, + isMax](fir::FirOpBuilder &builder, + mlir::func::FuncOp &funcOp) { + genRuntimeMinMaxlocBody(builder, funcOp, isMax, rank, maskRank, inputType, + logicalElemType, outType); }; mlir::func::FuncOp newFunc = getOrCreateFunction(builder, funcName, typeGenerator, bodyGenerator); builder.create(loc, newFunc, - mlir::ValueRange{args[0], args[1], args[5]}); + mlir::ValueRange{args[0], args[1], mask}); call->dropAllReferences(); call->erase(); } @@ -1279,11 +1289,11 @@ void SimplifyIntrinsicsPass::runOnOperation() { // RTNAME(Sum)(const Descriptor &x, const char *source, int line, // int dim, const Descriptor *mask) // - if (funcName.startswith(RTNAME_STRING(Sum))) { + if (funcName.starts_with(RTNAME_STRING(Sum))) { simplifyIntOrFloatReduction(call, kindMap, genRuntimeSumBody); return; } - if (funcName.startswith(RTNAME_STRING(DotProduct))) { + if (funcName.starts_with(RTNAME_STRING(DotProduct))) { LLVM_DEBUG(llvm::dbgs() << "Handling " << funcName << "\n"); LLVM_DEBUG(llvm::dbgs() << "Call operation:\n"; op->dump(); llvm::dbgs() << "\n"); @@ -1350,24 +1360,28 @@ void SimplifyIntrinsicsPass::runOnOperation() { llvm::dbgs() << "\n"); return; } - if (funcName.startswith(RTNAME_STRING(Maxval))) { + if (funcName.starts_with(RTNAME_STRING(Maxval))) { simplifyIntOrFloatReduction(call, kindMap, genRuntimeMaxvalBody); return; } - if (funcName.startswith(RTNAME_STRING(Count))) { + if (funcName.starts_with(RTNAME_STRING(Count))) { simplifyLogicalDim0Reduction(call, kindMap, genRuntimeCountBody); return; } - if (funcName.startswith(RTNAME_STRING(Any))) { + if (funcName.starts_with(RTNAME_STRING(Any))) { simplifyLogicalDim1Reduction(call, kindMap, genRuntimeAnyBody); return; } - if (funcName.endswith(RTNAME_STRING(All))) { + if (funcName.ends_with(RTNAME_STRING(All))) { simplifyLogicalDim1Reduction(call, kindMap, genRuntimeAllBody); return; } - if (funcName.startswith(RTNAME_STRING(Minloc))) { - simplifyMinlocReduction(call, kindMap); + if (funcName.starts_with(RTNAME_STRING(Minloc))) { + simplifyMinMaxlocReduction(call, kindMap, false); + return; + } + if (funcName.starts_with(RTNAME_STRING(Maxloc))) { + simplifyMinMaxlocReduction(call, kindMap, true); return; } } diff --git a/flang/lib/Optimizer/Transforms/StackArrays.cpp b/flang/lib/Optimizer/Transforms/StackArrays.cpp index b51e2aae1a9d5109d64e1865a058cd7909c69561..1c213abefe6f5f87ca3fcff0195d49ca2fa5176f 100644 --- a/flang/lib/Optimizer/Transforms/StackArrays.cpp +++ b/flang/lib/Optimizer/Transforms/StackArrays.cpp @@ -449,7 +449,7 @@ StackArraysAnalysisWrapper::analyseFunction(mlir::Operation *func) { const LatticePoint *lattice = solver.lookupState(op); // there will be no lattice for an unreachable block if (lattice) - point.join(*lattice); + (void)point.join(*lattice); }; func->walk([&](mlir::func::ReturnOp child) { joinOperationLattice(child); }); func->walk([&](fir::UnreachableOp child) { joinOperationLattice(child); }); diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index c070bc1de37352f1d3e118c1310f8b63777126a6..0dd95d69d3c662864fa87053e72fac802c22ce4f 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -1151,8 +1151,9 @@ TYPE_PARSER(construct(name, // R913 structure-component -> data-ref // The final part-ref in the data-ref is not allowed to have subscripts. -TYPE_PARSER(construct( - construct(some(Parser{} / percentOrDot)), name)) +TYPE_CONTEXT_PARSER("component"_en_US, + construct( + construct(some(Parser{} / percentOrDot)), name)) // R919 subscript -> scalar-int-expr constexpr auto subscript{scalarIntExpr}; diff --git a/flang/lib/Parser/executable-parsers.cpp b/flang/lib/Parser/executable-parsers.cpp index 892c612d0c4dc45622b2b2b98aeaeda01af63fae..de2be017508c370b07b038ca27f32a0bef81023f 100644 --- a/flang/lib/Parser/executable-parsers.cpp +++ b/flang/lib/Parser/executable-parsers.cpp @@ -92,9 +92,9 @@ TYPE_CONTEXT_PARSER("execution part"_en_US, // close-stmt | continue-stmt | cycle-stmt | deallocate-stmt | // endfile-stmt | error-stop-stmt | event-post-stmt | event-wait-stmt | // exit-stmt | fail-image-stmt | flush-stmt | form-team-stmt | -// goto-stmt | if-stmt | inquire-stmt | lock-stmt | nullify-stmt | -// open-stmt | pointer-assignment-stmt | print-stmt | read-stmt | -// return-stmt | rewind-stmt | stop-stmt | sync-all-stmt | +// goto-stmt | if-stmt | inquire-stmt | lock-stmt | notify-wait-stmt | +// nullify-stmt | open-stmt | pointer-assignment-stmt | print-stmt | +// read-stmt | return-stmt | rewind-stmt | stop-stmt | sync-all-stmt | // sync-images-stmt | sync-memory-stmt | sync-team-stmt | unlock-stmt | // wait-stmt | where-stmt | write-stmt | computed-goto-stmt | forall-stmt // R1159 continue-stmt -> CONTINUE @@ -119,6 +119,7 @@ TYPE_PARSER(first(construct(indirect(Parser{})), construct(indirect(Parser{})), construct(indirect(Parser{})), construct(indirect(Parser{})), + construct(indirect(Parser{})), construct(indirect(Parser{})), construct(indirect(Parser{})), construct(indirect(Parser{})), @@ -453,6 +454,13 @@ TYPE_CONTEXT_PARSER("STOP statement"_en_US, // parse time. TYPE_PARSER(construct(scalar(expr))) +// F2030: R1166 notify-wait-stmt -> +// NOTIFY WAIT ( notify-variable [, event-wait-spec-list] ) +TYPE_CONTEXT_PARSER("NOTIFY WAIT statement"_en_US, + construct( + "NOTIFY WAIT"_sptok >> "("_tok >> scalar(variable), + defaulted("," >> nonemptyList(Parser{})) / ")")) + // R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )] TYPE_CONTEXT_PARSER("SYNC ALL statement"_en_US, construct("SYNC ALL"_sptok >> @@ -486,15 +494,14 @@ TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US, // EVENT WAIT ( event-variable [, event-wait-spec-list] ) TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US, construct("EVENT WAIT"_sptok >> "("_tok >> scalar(variable), - defaulted("," >> nonemptyList(Parser{})) / - ")")) + defaulted("," >> nonemptyList(Parser{})) / ")")) // R1174 until-spec -> UNTIL_COUNT = scalar-int-expr constexpr auto untilSpec{"UNTIL_COUNT =" >> scalarIntExpr}; // R1173 event-wait-spec -> until-spec | sync-stat -TYPE_PARSER(construct(untilSpec) || - construct(statOrErrmsg)) +TYPE_PARSER(construct(untilSpec) || + construct(statOrErrmsg)) // R1177 team-variable -> scalar-variable constexpr auto teamVariable{scalar(variable)}; diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp index 79cdaccf1fbfec180f277453e8a4a1fd9298dc19..68d7d9f0c53c4751ddb9091e68e906de77f6a97a 100644 --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -139,16 +139,18 @@ void Prescanner::Statement() { SkipSpaces(); } } else { - // Compiler directive. Emit normalized sentinel. + // Compiler directive. Emit normalized sentinel, squash following spaces. EmitChar(tokens, '!'); ++at_, ++column_; for (const char *sp{directiveSentinel_}; *sp != '\0'; ++sp, ++at_, ++column_) { EmitChar(tokens, *sp); } - if (*at_ == ' ') { + if (*at_ == ' ' || *at_ == '\t') { EmitChar(tokens, ' '); - ++at_, ++column_; + while (*at_ == ' ' || *at_ == '\t') { + ++at_, ++column_; + } } tokens.CloseToken(); } diff --git a/flang/lib/Parser/source.cpp b/flang/lib/Parser/source.cpp index d0fe399424e1395bbe525631c63b562f196a01e4..4b4fed64a1a40a3bd61edc1480ac301683b7202c 100644 --- a/flang/lib/Parser/source.cpp +++ b/flang/lib/Parser/source.cpp @@ -46,7 +46,7 @@ void SourceFile::RecordLineStarts() { void SourceFile::IdentifyPayload() { llvm::StringRef content{buf_->getBufferStart(), buf_->getBufferSize()}; constexpr llvm::StringLiteral UTF8_BOM{"\xef\xbb\xbf"}; - if (content.startswith(UTF8_BOM)) { + if (content.starts_with(UTF8_BOM)) { bom_end_ = UTF8_BOM.size(); encoding_ = Encoding::UTF_8; } diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 6d9d176216325c43791b910f394aeea03eb024ca..1df49a688a12a0143d3855d3be9e46da65823327 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -1150,6 +1150,11 @@ public: void Unparse(const FailImageStmt &) { // R1163 Word("FAIL IMAGE"); } + void Unparse(const NotifyWaitStmt &x) { // F2023: R1166 + Word("NOTIFY WAIT ("), Walk(std::get>(x.t)); + Walk(", ", std::get>(x.t), ", "); + Put(')'); + } void Unparse(const SyncAllStmt &x) { // R1164 Word("SYNC ALL ("), Walk(x.v, ", "), Put(')'); } @@ -1169,7 +1174,7 @@ public: Word("EVENT POST ("), Walk(std::get(x.t)); Walk(", ", std::get>(x.t), ", "), Put(')'); } - void Before(const EventWaitStmt::EventWaitSpec &x) { // R1173, R1174 + void Before(const EventWaitSpec &x) { // R1173, R1174 common::visit(common::visitors{ [&](const ScalarIntExpr &) { Word("UNTIL_COUNT="); }, [](const StatOrErrmsg &) {}, @@ -1178,7 +1183,7 @@ public: } void Unparse(const EventWaitStmt &x) { // R1170 Word("EVENT WAIT ("), Walk(std::get(x.t)); - Walk(", ", std::get>(x.t), ", "); + Walk(", ", std::get>(x.t), ", "); Put(')'); } void Unparse(const FormTeamStmt &x) { // R1175, R1177 diff --git a/flang/lib/Semantics/check-coarray.cpp b/flang/lib/Semantics/check-coarray.cpp index 77b198284e050165cf6216d554e0a60e52f99db7..106af7960fa94787a794052f87e19ec340d9ce82 100644 --- a/flang/lib/Semantics/check-coarray.cpp +++ b/flang/lib/Semantics/check-coarray.cpp @@ -177,32 +177,15 @@ void CoarrayChecker::Leave(const parser::SyncTeamStmt &x) { CheckSyncStatList(context_, std::get>(x.t)); } -void CoarrayChecker::Leave(const parser::EventPostStmt &x) { - CheckSyncStatList(context_, std::get>(x.t)); - CheckEventVariable(context_, std::get(x.t)); -} - -void CoarrayChecker::Leave(const parser::EventWaitStmt &x) { - const auto &eventVar{std::get(x.t)}; - - if (const auto *expr{GetExpr(context_, eventVar)}) { - if (ExtractCoarrayRef(expr)) { - context_.Say(parser::FindSourceLocation(eventVar), // C1177 - "A event-variable in a EVENT WAIT statement may not be a coindexed object"_err_en_US); - } else { - CheckEventVariable(context_, eventVar); - } - } - +static void CheckEventWaitSpecList(SemanticsContext &context, + const std::list &eventWaitSpecList) { bool gotStat{false}, gotMsg{false}, gotUntil{false}; - using EventWaitSpec = parser::EventWaitStmt::EventWaitSpec; - for (const EventWaitSpec &eventWaitSpec : - std::get>(x.t)) { + for (const parser::EventWaitSpec &eventWaitSpec : eventWaitSpecList) { common::visit( common::visitors{ [&](const parser::ScalarIntExpr &untilCount) { if (gotUntil) { - context_.Say( // C1178 + context.Say( // C1178 "Until-spec in a event-wait-spec-list may not be repeated"_err_en_US); } gotUntil = true; @@ -212,17 +195,17 @@ void CoarrayChecker::Leave(const parser::EventWaitStmt &x) { common::visitors{ [&](const parser::StatVariable &stat) { if (gotStat) { - context_.Say( // C1178 + context.Say( // C1178 "A stat-variable in a event-wait-spec-list may not be repeated"_err_en_US); } gotStat = true; }, [&](const parser::MsgVariable &var) { - WarnOnDeferredLengthCharacterScalar(context_, - GetExpr(context_, var), + WarnOnDeferredLengthCharacterScalar(context, + GetExpr(context, var), var.v.thing.thing.GetSource(), "ERRMSG="); if (gotMsg) { - context_.Say( // C1178 + context.Say( // C1178 "A errmsg-variable in a event-wait-spec-list may not be repeated"_err_en_US); } gotMsg = true; @@ -230,7 +213,7 @@ void CoarrayChecker::Leave(const parser::EventWaitStmt &x) { }, statOrErrmsg.u); CheckCoindexedStatOrErrmsg( - context_, statOrErrmsg, "event-wait-spec-list"); + context, statOrErrmsg, "event-wait-spec-list"); }, }, @@ -238,6 +221,48 @@ void CoarrayChecker::Leave(const parser::EventWaitStmt &x) { } } +void CoarrayChecker::Leave(const parser::NotifyWaitStmt &x) { + const auto ¬ifyVar{std::get>(x.t)}; + + if (const auto *expr{GetExpr(context_, notifyVar)}) { + if (ExtractCoarrayRef(expr)) { + context_.Say(parser::FindSourceLocation(notifyVar), // F2023 - C1178 + "A notify-variable in a NOTIFY WAIT statement may not be a coindexed object"_err_en_US); + } else if (!IsNotifyType(evaluate::GetDerivedTypeSpec( + expr->GetType()))) { // F2023 - C1177 + context_.Say(parser::FindSourceLocation(notifyVar), + "The notify-variable must be of type NOTIFY_TYPE from module ISO_FORTRAN_ENV"_err_en_US); + } else if (!evaluate::IsCoarray(*expr)) { // F2023 - C1612 + context_.Say(parser::FindSourceLocation(notifyVar), + "The notify-variable must be a coarray"_err_en_US); + } + } + + CheckEventWaitSpecList( + context_, std::get>(x.t)); +} + +void CoarrayChecker::Leave(const parser::EventPostStmt &x) { + CheckSyncStatList(context_, std::get>(x.t)); + CheckEventVariable(context_, std::get(x.t)); +} + +void CoarrayChecker::Leave(const parser::EventWaitStmt &x) { + const auto &eventVar{std::get(x.t)}; + + if (const auto *expr{GetExpr(context_, eventVar)}) { + if (ExtractCoarrayRef(expr)) { + context_.Say(parser::FindSourceLocation(eventVar), // C1177 + "A event-variable in a EVENT WAIT statement may not be a coindexed object"_err_en_US); + } else { + CheckEventVariable(context_, eventVar); + } + } + + CheckEventWaitSpecList( + context_, std::get>(x.t)); +} + void CoarrayChecker::Leave(const parser::UnlockStmt &x) { CheckSyncStatList(context_, std::get>(x.t)); } diff --git a/flang/lib/Semantics/check-coarray.h b/flang/lib/Semantics/check-coarray.h index 251ee980d8a5298ef78b125a015d4d50b11b671f..0af9a880fd31a71dc4bfb18371771314ccfedd33 100644 --- a/flang/lib/Semantics/check-coarray.h +++ b/flang/lib/Semantics/check-coarray.h @@ -23,6 +23,7 @@ struct EventPostStmt; struct EventWaitStmt; struct FormTeamStmt; struct ImageSelector; +struct NotifyWaitStmt; struct SyncAllStmt; struct SyncImagesStmt; struct SyncMemoryStmt; @@ -41,6 +42,7 @@ public: void Leave(const parser::SyncImagesStmt &); void Leave(const parser::SyncMemoryStmt &); void Leave(const parser::SyncTeamStmt &); + void Leave(const parser::NotifyWaitStmt &); void Leave(const parser::EventPostStmt &); void Leave(const parser::EventWaitStmt &); void Leave(const parser::UnlockStmt &); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index e1cd34ddf65b6ba296abd9b44d0c0e5ff897896a..64fc7de120873a5516112778afeec6d0a3ea79cd 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -698,7 +698,7 @@ protected: bool CheckPossibleBadForwardRef(const Symbol &); bool inSpecificationPart_{false}; - bool inDataStmtObject_{false}; + bool deferImplicitTyping_{false}; bool inEquivalenceStmt_{false}; // Some information is collected from a specification part for deferred @@ -1629,6 +1629,7 @@ private: bool BeginScopeForNode(const ProgramTree &); void EndScopeForNode(const ProgramTree &); void FinishSpecificationParts(const ProgramTree &); + void FinishExecutionParts(const ProgramTree &); void FinishDerivedTypeInstantiation(Scope &); void ResolveExecutionParts(const ProgramTree &); void UseCUDABuiltinNames(); @@ -2533,7 +2534,7 @@ void ScopeHandler::ApplyImplicitRules( // or object, it'll be caught later. return; } - if (inDataStmtObject_) { + if (deferImplicitTyping_) { return; } if (!context().HasError(symbol)) { @@ -2709,7 +2710,7 @@ const DeclTypeSpec &ScopeHandler::MakeLogicalType(int kind) { } void ScopeHandler::NotePossibleBadForwardRef(const parser::Name &name) { - if (inSpecificationPart_ && !inDataStmtObject_ && name.symbol) { + if (inSpecificationPart_ && !deferImplicitTyping_ && name.symbol) { auto kind{currScope().kind()}; if ((kind == Scope::Kind::Subprogram && !currScope().IsStmtFunction()) || kind == Scope::Kind::BlockConstruct) { @@ -2904,7 +2905,7 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { } for (const auto &[name, symbol] : *useModuleScope_) { if (symbol->attrs().test(Attr::PUBLIC) && !IsUseRenamed(symbol->name()) && - (!symbol->attrs().test(Attr::INTRINSIC) || + (!symbol->implicitAttrs().test(Attr::INTRINSIC) || symbol->has()) && !symbol->has() && useNames.count(name) == 0) { SourceName location{x.moduleName.source}; @@ -2998,7 +2999,7 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName, details->add_occurrence(location, *useModuleScope_); return; } - + const Symbol &useUltimate{useSymbol.GetUltimate()}; if (localSymbol.has()) { localSymbol.set_details(UseDetails{localName, useSymbol}); localSymbol.attrs() = @@ -3010,7 +3011,6 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName, } Symbol &localUltimate{localSymbol.GetUltimate()}; - const Symbol &useUltimate{useSymbol.GetUltimate()}; if (&localUltimate == &useUltimate) { // use-associating the same symbol again -- ok return; @@ -3044,13 +3044,19 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName, checkAmbiguousDerivedType(&useUltimate, localGeneric->derivedType()); } else if (&useUltimate == &BypassGeneric(localUltimate).GetUltimate()) { return; // nothing to do; used subprogram is local's specific + } else if (useUltimate.attrs().test(Attr::INTRINSIC) && + useUltimate.name() == localSymbol.name()) { + return; // local generic can extend intrinsic } } else if (useGeneric) { if (localUltimate.has()) { combine = checkAmbiguousDerivedType(&localUltimate, useGeneric->derivedType()); - } else if (&localUltimate == &BypassGeneric(useUltimate).GetUltimate()) { - // Local is the specific of the used generic; replace it. + } else if (&localUltimate == &BypassGeneric(useUltimate).GetUltimate() || + (localSymbol.attrs().test(Attr::INTRINSIC) && + localUltimate.name() == useUltimate.name())) { + // Local is the specific of the used generic or an intrinsic with the + // same name; replace it. EraseSymbol(localSymbol); Symbol &newSymbol{MakeSymbol(localName, useUltimate.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE}, @@ -3058,23 +3064,22 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName, newSymbol.flags() = useSymbol.flags(); return; } + } else if (localUltimate.name() != useUltimate.name()) { + // not the same procedure + } else if (localUltimate.attrs().test(Attr::INTRINSIC) && + useUltimate.attrs().test(Attr::INTRINSIC)) { + return; } else { auto localClass{ClassifyProcedure(localUltimate)}; auto useClass{ClassifyProcedure(useUltimate)}; - if (localClass == useClass && - (localClass == ProcedureDefinitionClass::Intrinsic || - localClass == ProcedureDefinitionClass::External) && - localUltimate.name() == useUltimate.name()) { + if (localClass == ProcedureDefinitionClass::External && + useClass == ProcedureDefinitionClass::External) { auto localChars{evaluate::characteristics::Procedure::Characterize( localUltimate, GetFoldingContext())}; auto useChars{evaluate::characteristics::Procedure::Characterize( useUltimate, GetFoldingContext())}; - if (localChars && useChars) { - if (*localChars == *useChars) { - // Same intrinsic or external procedure defined identically in two - // modules - return; - } + if (localChars && useChars && *localChars == *useChars) { + return; // same procedure defined identically in two modules } } } @@ -4794,9 +4799,15 @@ Symbol &DeclarationVisitor::HandleAttributeStmt( } } } else if (symbol && symbol->has()) { - Say(currStmtSource().value(), - "Cannot change %s attribute on use-associated '%s'"_err_en_US, - EnumToString(attr), name.source); + if (symbol->GetUltimate().attrs().test(attr)) { + Say(currStmtSource().value(), + "Use-associated '%s' already has '%s' attribute"_warn_en_US, + name.source, EnumToString(attr)); + } else { + Say(currStmtSource().value(), + "Cannot change %s attribute on use-associated '%s'"_err_en_US, + EnumToString(attr), name.source); + } return *symbol; } if (!symbol) { @@ -5929,9 +5940,9 @@ void DeclarationVisitor::Post(const parser::BasedPointer &bp) { } if (const auto *pointeeType{pointee->GetType()}) { if (const auto *derived{pointeeType->AsDerived()}) { - if (!derived->typeSymbol().get().sequence()) { + if (!IsSequenceOrBindCType(derived)) { Say(pointeeName, - "Type of Cray pointee '%s' is a non-sequence derived type"_err_en_US); + "Type of Cray pointee '%s' is a derived type that is neither SEQUENCE nor BIND(C)"_err_en_US); } } } @@ -6166,15 +6177,13 @@ void DeclarationVisitor::CheckCommonBlocks() { Say(name, "Unlimited polymorphic pointer '%s' may not appear in a COMMON block"_err_en_US); } else if (const auto *derived{type->AsDerived()}) { - auto &typeSymbol{derived->typeSymbol()}; - if (!typeSymbol.attrs().test(Attr::BIND_C) && - !typeSymbol.get().sequence()) { + if (!IsSequenceOrBindCType(derived)) { Say(name, "Derived type '%s' in COMMON block must have the BIND or" " SEQUENCE attribute"_err_en_US); } UnorderedSymbolSet typeSet; - CheckCommonBlockDerivedType(name, typeSymbol, typeSet); + CheckCommonBlockDerivedType(name, derived->typeSymbol(), typeSet); } } } @@ -6244,8 +6253,8 @@ bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction( // recreated for it later on demand, but capturing its result type here // will make GetType() return a correct result without having to // probe the intrinsics table again. - Symbol &symbol{ - MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC})}; + Symbol &symbol{MakeSymbol(InclusiveScope(), name.source, Attrs{})}; + SetImplicitAttr(symbol, Attr::INTRINSIC); CHECK(interface->functionResult.has_value()); evaluate::DynamicType dyType{ DEREF(interface->functionResult->GetTypeAndShape()).type()}; @@ -6792,7 +6801,8 @@ bool ConstructVisitor::Pre(const parser::DataStmtObject &x) { auto flagRestorer{common::ScopedSet(inSpecificationPart_, false)}; common::visit(common::visitors{ [&](const Indirection &y) { - auto restorer{common::ScopedSet(inDataStmtObject_, true)}; + auto restorer{ + common::ScopedSet(deferImplicitTyping_, true)}; Walk(y.value()); const parser::Name &first{ parser::GetFirstName(y.value())}; @@ -7376,7 +7386,7 @@ const parser::Name *DeclarationVisitor::ResolveName(const parser::Name &name) { } return &name; } - if (isImplicitNoneType() && !inDataStmtObject_) { + if (isImplicitNoneType() && !deferImplicitTyping_) { Say(name, "No explicit type declared for '%s'"_err_en_US); return nullptr; } @@ -7538,7 +7548,15 @@ void DeclarationVisitor::Initialization(const parser::Name &name, common::visit( common::visitors{ [&](const parser::ConstantExpr &expr) { - NonPointerInitialization(name, expr); + Walk(expr); + if (IsNamedConstant(ultimate) || inComponentDecl) { + NonPointerInitialization(name, expr); + } else { + // Defer analysis so forward references to nested subprograms + // can be properly resolved when they appear in structure + // constructors. + ultimate.set(Symbol::Flag::InDataStmt); + } }, [&](const parser::NullInit &null) { // => NULL() Walk(null); @@ -7559,10 +7577,12 @@ void DeclarationVisitor::Initialization(const parser::Name &name, } } }, - [&](const parser::InitialDataTarget &) { + [&](const parser::InitialDataTarget &target) { // Defer analysis to the end of the specification part // so that forward references and attribute checks like SAVE // work better. + auto restorer{common::ScopedSet(deferImplicitTyping_, true)}; + Walk(target); ultimate.set(Symbol::Flag::InDataStmt); }, [&](const std::list> &values) { @@ -7580,12 +7600,27 @@ void DeclarationVisitor::PointerInitialization( Symbol &ultimate{name.symbol->GetUltimate()}; if (!context().HasError(ultimate)) { if (IsPointer(ultimate)) { - if (auto *details{ultimate.detailsIf()}) { - CHECK(!details->init()); - Walk(target); - if (MaybeExpr expr{EvaluateExpr(target)}) { - // Validation is done in declaration checking. + Walk(target); + if (MaybeExpr expr{EvaluateExpr(target)}) { + // Validation is done in declaration checking. + if (auto *details{ultimate.detailsIf()}) { + CHECK(!details->init()); details->set_init(std::move(*expr)); + ultimate.set(Symbol::Flag::InDataStmt, false); + } else if (auto *details{ultimate.detailsIf()}) { + // something like "REAL, EXTERNAL, POINTER :: p => t" + if (evaluate::IsNullProcedurePointer(*expr)) { + CHECK(!details->init()); + details->set_init(nullptr); + } else if (const Symbol * + targetSymbol{evaluate::UnwrapWholeSymbolDataRef(*expr)}) { + CHECK(!details->init()); + details->set_init(*targetSymbol); + } else { + Say(name, + "Procedure pointer '%s' must be initialized with a procedure name or NULL()"_err_en_US); + context().SetError(ultimate); + } } } } else { @@ -7625,27 +7660,23 @@ void DeclarationVisitor::PointerInitialization( void DeclarationVisitor::NonPointerInitialization( const parser::Name &name, const parser::ConstantExpr &expr) { - if (name.symbol) { + if (!context().HasError(name.symbol)) { Symbol &ultimate{name.symbol->GetUltimate()}; - if (!context().HasError(ultimate) && !context().HasError(name.symbol)) { + if (!context().HasError(ultimate)) { if (IsPointer(ultimate)) { Say(name, "'%s' is a pointer but is not initialized like one"_err_en_US); } else if (auto *details{ultimate.detailsIf()}) { - CHECK(!details->init()); - if (IsAllocatable(ultimate)) { + if (details->init()) { + } else if (IsAllocatable(ultimate)) { Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US); - return; - } - Walk(expr); - if (ultimate.owner().IsParameterizedDerivedType()) { + } else if (ultimate.owner().IsParameterizedDerivedType()) { // Save the expression for per-instantiation analysis. details->set_unanalyzedPDTComponentInit(&expr.thing.value()); - } else { - if (MaybeExpr folded{EvaluateNonPointerInitializer( - ultimate, expr, expr.thing.value().source)}) { - details->set_init(std::move(*folded)); - } + } else if (MaybeExpr folded{EvaluateNonPointerInitializer( + ultimate, expr, expr.thing.value().source)}) { + details->set_init(std::move(*folded)); + ultimate.set(Symbol::Flag::InDataStmt, false); } } else { Say(name, "'%s' is not an object that can be initialized"_err_en_US); @@ -7708,8 +7739,8 @@ void ResolveNamesVisitor::HandleProcedureName( auto *symbol{FindSymbol(NonDerivedTypeScope(), name)}; if (!symbol) { if (IsIntrinsic(name.source, flag)) { - symbol = - &MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC}); + symbol = &MakeSymbol(InclusiveScope(), name.source, Attrs{}); + SetImplicitAttr(*symbol, Attr::INTRINSIC); } else if (const auto ppcBuiltinScope = currScope().context().GetPPCBuiltinsScope()) { // Check if it is a builtin from the predefined module @@ -8047,6 +8078,11 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) { } else if (ultimate.has() || ultimate.has()) { genericDetails.set_specific(*existing); + } else if (ultimate.has()) { + if (existing->name() != symbolName || + !ultimate.attrs().test(Attr::INTRINSIC)) { + genericDetails.set_specific(*existing); + } } else if (ultimate.has()) { genericDetails.set_derivedType(*existing); } else if (&existing->owner() == &currScope()) { @@ -8409,6 +8445,7 @@ bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) { ResolveSpecificationParts(root); FinishSpecificationParts(root); ResolveExecutionParts(root); + FinishExecutionParts(root); ResolveAccParts(context(), x); ResolveOmpParts(context(), x); return false; @@ -8826,6 +8863,8 @@ public: } } + bool Pre(const parser::BlockConstruct &x) { return true; } + void Post(const parser::ProcInterface &pi) { if (const auto *name{std::get_if(&pi.u)}) { resolver_.CheckExplicitInterface(*name); @@ -8856,7 +8895,6 @@ public: resolver_.CheckBindings(tbps); } } - bool Pre(const parser::StmtFunctionStmt &stmtFunc) { return false; } private: void Init(const parser::Name &name, @@ -8865,6 +8903,9 @@ private: if (const auto *target{ std::get_if(&init->u)}) { resolver_.PointerInitialization(name, *target); + } else if (const auto *expr{ + std::get_if(&init->u)}) { + resolver_.NonPointerInitialization(name, *expr); } } } @@ -8879,15 +8920,16 @@ void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree &node) { if (!node.scope()) { return; // error occurred creating scope } + auto flagRestorer{common::ScopedSet(inSpecificationPart_, true)}; SetScope(*node.scope()); - // The initializers of pointers, the default initializers of pointer - // components, non-deferred type-bound procedure bindings have not - // yet been traversed. - // We do that now, when any (formerly) forward references that appear + // The initializers of pointers and non-PARAMETER objects, the default + // initializers of components, and non-deferred type-bound procedure + // bindings have not yet been traversed. + // We do that now, when any forward references that appeared // in those initializers will resolve to the right symbols without - // incurring spurious errors with IMPLICIT NONE. + // incurring spurious errors with IMPLICIT NONE or forward references + // to nested subprograms. DeferredCheckVisitor{*this}.Walk(node.spec()); - DeferredCheckVisitor{*this}.Walk(node.exec()); // for BLOCK for (Scope &childScope : currScope().children()) { if (childScope.IsParameterizedDerivedTypeInstantiation()) { FinishDerivedTypeInstantiation(childScope); @@ -8898,6 +8940,18 @@ void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree &node) { } } +void ResolveNamesVisitor::FinishExecutionParts(const ProgramTree &node) { + if (node.scope()) { + SetScope(*node.scope()); + if (node.exec()) { + DeferredCheckVisitor{*this}.Walk(*node.exec()); + } + for (const auto &child : node.children()) { + FinishExecutionParts(child); + } + } +} + // Duplicate and fold component object pointer default initializer designators // using the actual type parameter values of each particular instantiation. // Validation is done later in declaration checking. diff --git a/flang/module/__fortran_builtins.f90 b/flang/module/__fortran_builtins.f90 index 0bc66def847edea4f1713b9072a0a23867e3a865..0566ae6327d76d8ce3491007fbcbed42b5de6092 100644 --- a/flang/module/__fortran_builtins.f90 +++ b/flang/module/__fortran_builtins.f90 @@ -32,6 +32,10 @@ module __fortran_builtins integer(kind=int64), private :: __count end type + type :: __builtin_notify_type + integer(kind=int64), private :: __count + end type + type :: __builtin_lock_type integer(kind=int64), private :: __count end type diff --git a/flang/module/iso_fortran_env.f90 b/flang/module/iso_fortran_env.f90 index f1d540bc8e45198b7de1667e2db80070a7c38c4f..cd3c06f8c75660a9abc647e6980f429e9141bfe8 100644 --- a/flang/module/iso_fortran_env.f90 +++ b/flang/module/iso_fortran_env.f90 @@ -9,12 +9,13 @@ ! See Fortran 2018, clause 16.10.2 ! TODO: These are placeholder values so that some tests can be run. -include '../include/flang/Runtime/magic-numbers.h' ! IOSTAT values +include '../include/flang/Runtime/magic-numbers.h' module iso_fortran_env use __fortran_builtins, only: & event_type => __builtin_event_type, & + notify_type => __builtin_notify_type, & lock_type => __builtin_lock_type, & team_type => __builtin_team_type, & atomic_int_kind => __builtin_atomic_int_kind, & @@ -23,6 +24,7 @@ module iso_fortran_env compiler_version => __builtin_compiler_version implicit none + private count ! TODO: Use PACK([x],test) in place of the array constructor idiom ! [(x, integer::j=1,COUNT([test]))] below once PACK() can be folded. @@ -129,8 +131,9 @@ module iso_fortran_env integer, parameter :: current_team = -1, initial_team = -2, parent_team = -3 - integer, parameter :: input_unit = 5, output_unit = 6 - integer, parameter :: error_unit = 0 + integer, parameter :: output_unit = FORTRAN_DEFAULT_OUTPUT_UNIT + integer, parameter :: input_unit = FORTRAN_DEFAULT_INPUT_UNIT + integer, parameter :: error_unit = FORTRAN_ERROR_UNIT integer, parameter :: iostat_end = FORTRAN_RUNTIME_IOSTAT_END integer, parameter :: iostat_eor = FORTRAN_RUNTIME_IOSTAT_EOR integer, parameter :: iostat_inquire_internal_unit = & diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt index bf3aa5af3c88e33ce1d7044e25ea235a08b65e0e..d6df15b7f6e078769ef518f93dc1dca9b5ba92fc 100644 --- a/flang/runtime/CMakeLists.txt +++ b/flang/runtime/CMakeLists.txt @@ -90,16 +90,16 @@ set(sources array-constructor.cpp assign.cpp buffer.cpp + character.cpp command.cpp complex-powi.cpp complex-reduction.c - copy.cpp - character.cpp connection.cpp - derived.cpp + copy.cpp derived-api.cpp - descriptor.cpp + derived.cpp descriptor-io.cpp + descriptor.cpp dot-product.cpp edit-input.cpp edit-output.cpp @@ -112,10 +112,10 @@ set(sources format.cpp inquiry.cpp internal-unit.cpp - iostat.cpp io-api.cpp io-error.cpp io-stmt.cpp + iostat.cpp main.cpp matmul-transpose.cpp matmul.cpp @@ -124,11 +124,11 @@ set(sources namelist.cpp non-tbp-dio.cpp numeric.cpp + pointer.cpp + product.cpp ragged.cpp random.cpp reduction.cpp - pointer.cpp - product.cpp stat.cpp stop.cpp sum.cpp @@ -140,8 +140,8 @@ set(sources transformational.cpp type-code.cpp type-info.cpp - unit.cpp unit-map.cpp + unit.cpp utf.cpp ) @@ -152,10 +152,29 @@ option(FLANG_EXPERIMENTAL_CUDA_RUNTIME # List of files that are buildable for all devices. set(supported_files ISO_Fortran_binding.cpp + allocatable.cpp + array-constructor.cpp assign.cpp + character.cpp + copy.cpp + derived-api.cpp derived.cpp descriptor.cpp + dot-product.cpp + extrema.cpp + findloc.cpp + inquiry.cpp + matmul-transpose.cpp + matmul.cpp + memory.cpp + misc-intrinsic.cpp + numeric.cpp + pointer.cpp + product.cpp + ragged.cpp stat.cpp + sum.cpp + support.cpp terminator.cpp tools.cpp transformational.cpp @@ -188,6 +207,10 @@ if (FLANG_EXPERIMENTAL_CUDA_RUNTIME) if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "NVIDIA") set(CUDA_COMPILE_OPTIONS --expt-relaxed-constexpr + # Disable these warnings: + # 'long double' is treated as 'double' in device code + -Xcudafe --diag_suppress=20208 + -Xcudafe --display_error_number ) endif() set_source_files_properties(${supported_files} PROPERTIES COMPILE_OPTIONS diff --git a/flang/runtime/allocatable.cpp b/flang/runtime/allocatable.cpp index 409255aaa214deee0cb37b6d3c87634d570b5c06..e69795e6f824ba41f09d1ee505818e57b752fc5b 100644 --- a/flang/runtime/allocatable.cpp +++ b/flang/runtime/allocatable.cpp @@ -18,8 +18,9 @@ namespace Fortran::runtime { extern "C" { +RT_EXT_API_GROUP_BEGIN -void RTNAME(AllocatableInitIntrinsic)(Descriptor &descriptor, +void RTDEF(AllocatableInitIntrinsic)(Descriptor &descriptor, TypeCategory category, int kind, int rank, int corank) { INTERNAL_CHECK(corank == 0); descriptor.Establish(TypeCode{category, kind}, @@ -27,21 +28,21 @@ void RTNAME(AllocatableInitIntrinsic)(Descriptor &descriptor, CFI_attribute_allocatable); } -void RTNAME(AllocatableInitCharacter)(Descriptor &descriptor, +void RTDEF(AllocatableInitCharacter)(Descriptor &descriptor, SubscriptValue length, int kind, int rank, int corank) { INTERNAL_CHECK(corank == 0); descriptor.Establish( kind, length, nullptr, rank, nullptr, CFI_attribute_allocatable); } -void RTNAME(AllocatableInitDerived)(Descriptor &descriptor, +void RTDEF(AllocatableInitDerived)(Descriptor &descriptor, const typeInfo::DerivedType &derivedType, int rank, int corank) { INTERNAL_CHECK(corank == 0); descriptor.Establish( derivedType, nullptr, rank, nullptr, CFI_attribute_allocatable); } -void RTNAME(AllocatableInitIntrinsicForAllocate)(Descriptor &descriptor, +void RTDEF(AllocatableInitIntrinsicForAllocate)(Descriptor &descriptor, TypeCategory category, int kind, int rank, int corank) { if (descriptor.IsAllocated()) { return; @@ -49,7 +50,7 @@ void RTNAME(AllocatableInitIntrinsicForAllocate)(Descriptor &descriptor, RTNAME(AllocatableInitIntrinsic)(descriptor, category, kind, rank, corank); } -void RTNAME(AllocatableInitCharacterForAllocate)(Descriptor &descriptor, +void RTDEF(AllocatableInitCharacterForAllocate)(Descriptor &descriptor, SubscriptValue length, int kind, int rank, int corank) { if (descriptor.IsAllocated()) { return; @@ -57,7 +58,7 @@ void RTNAME(AllocatableInitCharacterForAllocate)(Descriptor &descriptor, RTNAME(AllocatableInitCharacter)(descriptor, length, kind, rank, corank); } -void RTNAME(AllocatableInitDerivedForAllocate)(Descriptor &descriptor, +void RTDEF(AllocatableInitDerivedForAllocate)(Descriptor &descriptor, const typeInfo::DerivedType &derivedType, int rank, int corank) { if (descriptor.IsAllocated()) { return; @@ -65,7 +66,7 @@ void RTNAME(AllocatableInitDerivedForAllocate)(Descriptor &descriptor, RTNAME(AllocatableInitDerived)(descriptor, derivedType, rank, corank); } -std::int32_t RTNAME(MoveAlloc)(Descriptor &to, Descriptor &from, +std::int32_t RTDEF(MoveAlloc)(Descriptor &to, Descriptor &from, const typeInfo::DerivedType *derivedType, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; @@ -110,21 +111,21 @@ std::int32_t RTNAME(MoveAlloc)(Descriptor &to, Descriptor &from, return StatOk; } -void RTNAME(AllocatableSetBounds)(Descriptor &descriptor, int zeroBasedDim, +void RTDEF(AllocatableSetBounds)(Descriptor &descriptor, int zeroBasedDim, SubscriptValue lower, SubscriptValue upper) { INTERNAL_CHECK(zeroBasedDim >= 0 && zeroBasedDim < descriptor.rank()); descriptor.GetDimension(zeroBasedDim).SetBounds(lower, upper); // The byte strides are computed when the object is allocated. } -void RTNAME(AllocatableSetDerivedLength)( +void RTDEF(AllocatableSetDerivedLength)( Descriptor &descriptor, int which, SubscriptValue x) { DescriptorAddendum *addendum{descriptor.Addendum()}; INTERNAL_CHECK(addendum != nullptr); addendum->SetLenParameterValue(which, x); } -void RTNAME(AllocatableApplyMold)( +void RTDEF(AllocatableApplyMold)( Descriptor &descriptor, const Descriptor &mold, int rank) { if (descriptor.IsAllocated()) { // 9.7.1.3 Return so the error can be emitted by AllocatableAllocate. @@ -133,7 +134,7 @@ void RTNAME(AllocatableApplyMold)( descriptor.ApplyMold(mold, rank); } -int RTNAME(AllocatableAllocate)(Descriptor &descriptor, bool hasStat, +int RTDEF(AllocatableAllocate)(Descriptor &descriptor, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!descriptor.IsAllocatable()) { @@ -155,7 +156,7 @@ int RTNAME(AllocatableAllocate)(Descriptor &descriptor, bool hasStat, return stat; } -int RTNAME(AllocatableAllocateSource)(Descriptor &alloc, +int RTDEF(AllocatableAllocateSource)(Descriptor &alloc, const Descriptor &source, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { int stat{RTNAME(AllocatableAllocate)( @@ -167,7 +168,7 @@ int RTNAME(AllocatableAllocateSource)(Descriptor &alloc, return stat; } -int RTNAME(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat, +int RTDEF(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!descriptor.IsAllocatable()) { @@ -182,7 +183,7 @@ int RTNAME(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat, errMsg, hasStat); } -int RTNAME(AllocatableDeallocatePolymorphic)(Descriptor &descriptor, +int RTDEF(AllocatableDeallocatePolymorphic)(Descriptor &descriptor, const typeInfo::DerivedType *derivedType, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { int stat{RTNAME(AllocatableDeallocate)( @@ -202,7 +203,7 @@ int RTNAME(AllocatableDeallocatePolymorphic)(Descriptor &descriptor, return stat; } -void RTNAME(AllocatableDeallocateNoFinal)( +void RTDEF(AllocatableDeallocateNoFinal)( Descriptor &descriptor, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!descriptor.IsAllocatable()) { @@ -217,5 +218,7 @@ void RTNAME(AllocatableDeallocateNoFinal)( } // TODO: AllocatableCheckLengthParameter + +RT_EXT_API_GROUP_END } } // namespace Fortran::runtime diff --git a/flang/runtime/array-constructor.cpp b/flang/runtime/array-constructor.cpp index 1be302eaaf1ae5b31ab4dc599b6f87afbde365ff..72e08feff7fd107098e7eb03a5f830826f9e44ea 100644 --- a/flang/runtime/array-constructor.cpp +++ b/flang/runtime/array-constructor.cpp @@ -9,6 +9,7 @@ #include "flang/Runtime/array-constructor.h" #include "derived.h" #include "terminator.h" +#include "tools.h" #include "type-info.h" #include "flang/Runtime/allocatable.h" #include "flang/Runtime/assign.h" @@ -23,7 +24,7 @@ namespace Fortran::runtime { // REAL(8), INTEGER(8), COMPLEX(4), ... -> 16 elements. // REAL(16), INTEGER(16), COMPLEX(8), ... -> 8 elements. // Bigger types -> 4 elements. -static SubscriptValue initialAllocationSize( +static RT_API_ATTRS SubscriptValue initialAllocationSize( SubscriptValue initialNumberOfElements, SubscriptValue elementBytes) { // Try to guess an optimal initial allocation size in number of elements to // avoid doing too many reallocation. @@ -36,9 +37,9 @@ static SubscriptValue initialAllocationSize( return std::max(numberOfElements, elementsForMinBytes); } -static void AllocateOrReallocateVectorIfNeeded(ArrayConstructorVector &vector, - Terminator &terminator, SubscriptValue previousToElements, - SubscriptValue fromElements) { +static RT_API_ATTRS void AllocateOrReallocateVectorIfNeeded( + ArrayConstructorVector &vector, Terminator &terminator, + SubscriptValue previousToElements, SubscriptValue fromElements) { Descriptor &to{vector.to}; if (to.IsAllocatable() && !to.IsAllocated()) { // The descriptor bounds may already be set here if the array constructor @@ -73,8 +74,8 @@ static void AllocateOrReallocateVectorIfNeeded(ArrayConstructorVector &vector, // realloc is undefined with zero new size and ElementBytes() may be null // if the character length is null, or if "from" is a zero sized array. if (newByteSize > 0) { - void *p{std::realloc(to.raw().base_addr, newByteSize)}; - RUNTIME_CHECK(terminator, p); + void *p{ReallocateMemoryOrCrash( + terminator, to.raw().base_addr, newByteSize)}; to.set_base_addr(p); } vector.actualAllocationSize = requestedAllocationSize; @@ -88,7 +89,9 @@ static void AllocateOrReallocateVectorIfNeeded(ArrayConstructorVector &vector, } extern "C" { -void RTNAME(InitArrayConstructorVector)(ArrayConstructorVector &vector, +RT_EXT_API_GROUP_BEGIN + +void RTDEF(InitArrayConstructorVector)(ArrayConstructorVector &vector, Descriptor &to, bool useValueLengthParameters, int vectorClassSize, const char *sourceFile, int sourceLine) { Terminator terminator{vector.sourceFile, vector.sourceLine}; @@ -102,7 +105,7 @@ void RTNAME(InitArrayConstructorVector)(ArrayConstructorVector &vector, actualAllocationSize, sourceFile, sourceLine, useValueLengthParameters}; } -void RTNAME(PushArrayConstructorValue)( +void RTDEF(PushArrayConstructorValue)( ArrayConstructorVector &vector, const Descriptor &from) { Terminator terminator{vector.sourceFile, vector.sourceLine}; Descriptor &to{vector.to}; @@ -166,7 +169,7 @@ void RTNAME(PushArrayConstructorValue)( vector.nextValuePosition += fromElements; } -void RTNAME(PushArrayConstructorSimpleScalar)( +void RTDEF(PushArrayConstructorSimpleScalar)( ArrayConstructorVector &vector, void *from) { Terminator terminator{vector.sourceFile, vector.sourceLine}; Descriptor &to{vector.to}; @@ -176,5 +179,7 @@ void RTNAME(PushArrayConstructorSimpleScalar)( std::memcpy(to.Element(subscript), from, to.ElementBytes()); ++vector.nextValuePosition; } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/character.cpp b/flang/runtime/character.cpp index 2afde7cd5e833afdf5826344aa5bbd46f4df077f..5049247397eb3c908d6b00703f5a3c8a597ad8c3 100644 --- a/flang/runtime/character.cpp +++ b/flang/runtime/character.cpp @@ -11,6 +11,7 @@ #include "tools.h" #include "flang/Common/bit-population-count.h" #include "flang/Common/uint128.h" +#include "flang/Runtime/character.h" #include "flang/Runtime/cpp-type.h" #include "flang/Runtime/descriptor.h" #include @@ -19,7 +20,8 @@ namespace Fortran::runtime { template -inline int CompareToBlankPadding(const CHAR *x, std::size_t chars) { +inline RT_API_ATTRS int CompareToBlankPadding( + const CHAR *x, std::size_t chars) { using UNSIGNED_CHAR = std::make_unsigned_t; const auto blank{static_cast(' ')}; for (; chars-- > 0; ++x) { @@ -34,13 +36,15 @@ inline int CompareToBlankPadding(const CHAR *x, std::size_t chars) { return 0; } +RT_OFFLOAD_API_GROUP_BEGIN + template -int CharacterScalarCompare( +RT_API_ATTRS int CharacterScalarCompare( const CHAR *x, const CHAR *y, std::size_t xChars, std::size_t yChars) { auto minChars{std::min(xChars, yChars)}; if constexpr (sizeof(CHAR) == 1) { // don't use for kind=2 or =4, that would fail on little-endian machines - int cmp{std::memcmp(x, y, minChars)}; + int cmp{Fortran::runtime::memcmp(x, y, minChars)}; if (cmp < 0) { return -1; } @@ -68,20 +72,22 @@ int CharacterScalarCompare( return -CompareToBlankPadding(y, yChars - minChars); } -template int CharacterScalarCompare( +template RT_API_ATTRS int CharacterScalarCompare( const char *x, const char *y, std::size_t xChars, std::size_t yChars); -template int CharacterScalarCompare(const char16_t *x, +template RT_API_ATTRS int CharacterScalarCompare(const char16_t *x, const char16_t *y, std::size_t xChars, std::size_t yChars); -template int CharacterScalarCompare(const char32_t *x, +template RT_API_ATTRS int CharacterScalarCompare(const char32_t *x, const char32_t *y, std::size_t xChars, std::size_t yChars); +RT_OFFLOAD_API_GROUP_END + // Shift count to use when converting between character lengths // and byte counts. template constexpr int shift{common::TrailingZeroBitCount(sizeof(CHAR))}; template -static void Compare(Descriptor &result, const Descriptor &x, +static RT_API_ATTRS void Compare(Descriptor &result, const Descriptor &x, const Descriptor &y, const Terminator &terminator) { RUNTIME_CHECK( terminator, x.rank() == y.rank() || x.rank() == 0 || y.rank() == 0); @@ -124,7 +130,7 @@ static void Compare(Descriptor &result, const Descriptor &x, } template -static void Adjust(CHAR *to, const CHAR *from, std::size_t chars) { +static RT_API_ATTRS void Adjust(CHAR *to, const CHAR *from, std::size_t chars) { if constexpr (ADJUSTR) { std::size_t j{chars}, k{chars}; for (; k > 0 && from[k - 1] == ' '; --k) { @@ -149,8 +155,8 @@ static void Adjust(CHAR *to, const CHAR *from, std::size_t chars) { } template -static void AdjustLRHelper(Descriptor &result, const Descriptor &string, - const Terminator &terminator) { +static RT_API_ATTRS void AdjustLRHelper(Descriptor &result, + const Descriptor &string, const Terminator &terminator) { int rank{string.rank()}; SubscriptValue ub[maxRank], stringAt[maxRank]; SubscriptValue elements{1}; @@ -177,7 +183,7 @@ static void AdjustLRHelper(Descriptor &result, const Descriptor &string, } template -void AdjustLR(Descriptor &result, const Descriptor &string, +RT_API_ATTRS void AdjustLR(Descriptor &result, const Descriptor &string, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; switch (string.raw().type) { @@ -197,7 +203,7 @@ void AdjustLR(Descriptor &result, const Descriptor &string, } template -inline std::size_t LenTrim(const CHAR *x, std::size_t chars) { +inline RT_API_ATTRS std::size_t LenTrim(const CHAR *x, std::size_t chars) { while (chars > 0 && x[chars - 1] == ' ') { --chars; } @@ -205,7 +211,7 @@ inline std::size_t LenTrim(const CHAR *x, std::size_t chars) { } template -static void LenTrim(Descriptor &result, const Descriptor &string, +static RT_API_ATTRS void LenTrim(Descriptor &result, const Descriptor &string, const Terminator &terminator) { int rank{string.rank()}; SubscriptValue ub[maxRank], stringAt[maxRank]; @@ -232,8 +238,8 @@ static void LenTrim(Descriptor &result, const Descriptor &string, } template -static void LenTrimKind(Descriptor &result, const Descriptor &string, int kind, - const Terminator &terminator) { +static RT_API_ATTRS void LenTrimKind(Descriptor &result, + const Descriptor &string, int kind, const Terminator &terminator) { switch (kind) { case 1: LenTrim, CHAR>( @@ -263,8 +269,8 @@ static void LenTrimKind(Descriptor &result, const Descriptor &string, int kind, // INDEX implementation template -inline std::size_t Index(const CHAR *x, std::size_t xLen, const CHAR *want, - std::size_t wantLen, bool back) { +inline RT_API_ATTRS std::size_t Index(const CHAR *x, std::size_t xLen, + const CHAR *want, std::size_t wantLen, bool back) { if (xLen < wantLen) { return 0; } @@ -329,8 +335,8 @@ inline std::size_t Index(const CHAR *x, std::size_t xLen, const CHAR *want, enum class CharFunc { Index, Scan, Verify }; template -inline std::size_t ScanVerify(const CHAR *x, std::size_t xLen, const CHAR *set, - std::size_t setLen, bool back) { +inline RT_API_ATTRS std::size_t ScanVerify(const CHAR *x, std::size_t xLen, + const CHAR *set, std::size_t setLen, bool back) { std::size_t at{back ? xLen : 1}; int increment{back ? -1 : 1}; for (; xLen-- > 0; at += increment) { @@ -352,8 +358,8 @@ inline std::size_t ScanVerify(const CHAR *x, std::size_t xLen, const CHAR *set, // Specialization for one-byte characters template -inline std::size_t ScanVerify(const char *x, std::size_t xLen, const char *set, - std::size_t setLen, bool back) { +inline RT_API_ATTRS std::size_t ScanVerify(const char *x, std::size_t xLen, + const char *set, std::size_t setLen, bool back) { std::size_t at{back ? xLen : 1}; int increment{back ? -1 : 1}; if (xLen > 0) { @@ -375,8 +381,8 @@ inline std::size_t ScanVerify(const char *x, std::size_t xLen, const char *set, } template -static void GeneralCharFunc(Descriptor &result, const Descriptor &string, - const Descriptor &arg, const Descriptor *back, +static RT_API_ATTRS void GeneralCharFunc(Descriptor &result, + const Descriptor &string, const Descriptor &arg, const Descriptor *back, const Terminator &terminator) { int rank{string.rank() ? string.rank() : arg.rank() ? arg.rank() @@ -433,9 +439,9 @@ static void GeneralCharFunc(Descriptor &result, const Descriptor &string, } template -static void GeneralCharFuncKind(Descriptor &result, const Descriptor &string, - const Descriptor &arg, const Descriptor *back, int kind, - const Terminator &terminator) { +static RT_API_ATTRS void GeneralCharFuncKind(Descriptor &result, + const Descriptor &string, const Descriptor &arg, const Descriptor *back, + int kind, const Terminator &terminator) { switch (kind) { case 1: GeneralCharFunc, CHAR, FUNC>( @@ -464,30 +470,9 @@ static void GeneralCharFuncKind(Descriptor &result, const Descriptor &string, } } -template -static void CopyAndPad( - TO *to, const FROM *from, std::size_t toChars, std::size_t fromChars) { - if constexpr (sizeof(TO) != sizeof(FROM)) { - std::size_t copyChars{std::min(toChars, fromChars)}; - for (std::size_t j{0}; j < copyChars; ++j) { - to[j] = from[j]; - } - for (std::size_t j{copyChars}; j < toChars; ++j) { - to[j] = static_cast(' '); - } - } else if (toChars <= fromChars) { - std::memcpy(to, from, toChars * sizeof(TO)); - } else { - std::memcpy(to, from, fromChars * sizeof(TO)); - for (std::size_t j{fromChars}; j < toChars; ++j) { - to[j] = static_cast(' '); - } - } -} - template -static void MaxMinHelper(Descriptor &accumulator, const Descriptor &x, - const Terminator &terminator) { +static RT_API_ATTRS void MaxMinHelper(Descriptor &accumulator, + const Descriptor &x, const Terminator &terminator) { RUNTIME_CHECK(terminator, accumulator.rank() == 0 || x.rank() == 0 || accumulator.rank() == x.rank()); @@ -545,7 +530,7 @@ static void MaxMinHelper(Descriptor &accumulator, const Descriptor &x, } template -static void MaxMin(Descriptor &accumulator, const Descriptor &x, +static RT_API_ATTRS void MaxMin(Descriptor &accumulator, const Descriptor &x, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; RUNTIME_CHECK(terminator, accumulator.raw().type == x.raw().type); @@ -566,8 +551,9 @@ static void MaxMin(Descriptor &accumulator, const Descriptor &x, } extern "C" { +RT_EXT_API_GROUP_BEGIN -void RTNAME(CharacterConcatenate)(Descriptor &accumulator, +void RTDEF(CharacterConcatenate)(Descriptor &accumulator, const Descriptor &from, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; RUNTIME_CHECK(terminator, @@ -616,7 +602,7 @@ void RTNAME(CharacterConcatenate)(Descriptor &accumulator, FreeMemory(old); } -void RTNAME(CharacterConcatenateScalar1)( +void RTDEF(CharacterConcatenateScalar1)( Descriptor &accumulator, const char *from, std::size_t chars) { Terminator terminator{__FILE__, __LINE__}; RUNTIME_CHECK(terminator, accumulator.rank() == 0); @@ -629,7 +615,7 @@ void RTNAME(CharacterConcatenateScalar1)( FreeMemory(old); } -int RTNAME(CharacterCompareScalar)(const Descriptor &x, const Descriptor &y) { +int RTDEF(CharacterCompareScalar)(const Descriptor &x, const Descriptor &y) { Terminator terminator{__FILE__, __LINE__}; RUNTIME_CHECK(terminator, x.rank() == 0); RUNTIME_CHECK(terminator, y.rank() == 0); @@ -653,22 +639,22 @@ int RTNAME(CharacterCompareScalar)(const Descriptor &x, const Descriptor &y) { return 0; } -int RTNAME(CharacterCompareScalar1)( +int RTDEF(CharacterCompareScalar1)( const char *x, const char *y, std::size_t xChars, std::size_t yChars) { return CharacterScalarCompare(x, y, xChars, yChars); } -int RTNAME(CharacterCompareScalar2)(const char16_t *x, const char16_t *y, +int RTDEF(CharacterCompareScalar2)(const char16_t *x, const char16_t *y, std::size_t xChars, std::size_t yChars) { return CharacterScalarCompare(x, y, xChars, yChars); } -int RTNAME(CharacterCompareScalar4)(const char32_t *x, const char32_t *y, +int RTDEF(CharacterCompareScalar4)(const char32_t *x, const char32_t *y, std::size_t xChars, std::size_t yChars) { return CharacterScalarCompare(x, y, xChars, yChars); } -void RTNAME(CharacterCompare)( +void RTDEF(CharacterCompare)( Descriptor &result, const Descriptor &x, const Descriptor &y) { Terminator terminator{__FILE__, __LINE__}; RUNTIME_CHECK(terminator, x.raw().type == y.raw().type); @@ -688,7 +674,7 @@ void RTNAME(CharacterCompare)( } } -std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes, +std::size_t RTDEF(CharacterAppend1)(char *lhs, std::size_t lhsBytes, std::size_t offset, const char *rhs, std::size_t rhsBytes) { if (auto n{std::min(lhsBytes - offset, rhsBytes)}) { std::memcpy(lhs + offset, rhs, n); @@ -697,7 +683,7 @@ std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes, return offset; } -void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset) { +void RTDEF(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset) { if (bytes > offset) { std::memset(lhs + offset, ' ', bytes - offset); } @@ -705,30 +691,30 @@ void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset) { // Intrinsic function entry points -void RTNAME(Adjustl)(Descriptor &result, const Descriptor &string, +void RTDEF(Adjustl)(Descriptor &result, const Descriptor &string, const char *sourceFile, int sourceLine) { AdjustLR(result, string, sourceFile, sourceLine); } -void RTNAME(Adjustr)(Descriptor &result, const Descriptor &string, +void RTDEF(Adjustr)(Descriptor &result, const Descriptor &string, const char *sourceFile, int sourceLine) { AdjustLR(result, string, sourceFile, sourceLine); } -std::size_t RTNAME(Index1)(const char *x, std::size_t xLen, const char *set, +std::size_t RTDEF(Index1)(const char *x, std::size_t xLen, const char *set, std::size_t setLen, bool back) { return Index(x, xLen, set, setLen, back); } -std::size_t RTNAME(Index2)(const char16_t *x, std::size_t xLen, +std::size_t RTDEF(Index2)(const char16_t *x, std::size_t xLen, const char16_t *set, std::size_t setLen, bool back) { return Index(x, xLen, set, setLen, back); } -std::size_t RTNAME(Index4)(const char32_t *x, std::size_t xLen, +std::size_t RTDEF(Index4)(const char32_t *x, std::size_t xLen, const char32_t *set, std::size_t setLen, bool back) { return Index(x, xLen, set, setLen, back); } -void RTNAME(Index)(Descriptor &result, const Descriptor &string, +void RTDEF(Index)(Descriptor &result, const Descriptor &string, const Descriptor &substring, const Descriptor *back, int kind, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; @@ -751,17 +737,17 @@ void RTNAME(Index)(Descriptor &result, const Descriptor &string, } } -std::size_t RTNAME(LenTrim1)(const char *x, std::size_t chars) { +std::size_t RTDEF(LenTrim1)(const char *x, std::size_t chars) { return LenTrim(x, chars); } -std::size_t RTNAME(LenTrim2)(const char16_t *x, std::size_t chars) { +std::size_t RTDEF(LenTrim2)(const char16_t *x, std::size_t chars) { return LenTrim(x, chars); } -std::size_t RTNAME(LenTrim4)(const char32_t *x, std::size_t chars) { +std::size_t RTDEF(LenTrim4)(const char32_t *x, std::size_t chars) { return LenTrim(x, chars); } -void RTNAME(LenTrim)(Descriptor &result, const Descriptor &string, int kind, +void RTDEF(LenTrim)(Descriptor &result, const Descriptor &string, int kind, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; switch (string.raw().type) { @@ -780,20 +766,20 @@ void RTNAME(LenTrim)(Descriptor &result, const Descriptor &string, int kind, } } -std::size_t RTNAME(Scan1)(const char *x, std::size_t xLen, const char *set, +std::size_t RTDEF(Scan1)(const char *x, std::size_t xLen, const char *set, std::size_t setLen, bool back) { return ScanVerify(x, xLen, set, setLen, back); } -std::size_t RTNAME(Scan2)(const char16_t *x, std::size_t xLen, +std::size_t RTDEF(Scan2)(const char16_t *x, std::size_t xLen, const char16_t *set, std::size_t setLen, bool back) { return ScanVerify(x, xLen, set, setLen, back); } -std::size_t RTNAME(Scan4)(const char32_t *x, std::size_t xLen, +std::size_t RTDEF(Scan4)(const char32_t *x, std::size_t xLen, const char32_t *set, std::size_t setLen, bool back) { return ScanVerify(x, xLen, set, setLen, back); } -void RTNAME(Scan)(Descriptor &result, const Descriptor &string, +void RTDEF(Scan)(Descriptor &result, const Descriptor &string, const Descriptor &set, const Descriptor *back, int kind, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; @@ -816,7 +802,7 @@ void RTNAME(Scan)(Descriptor &result, const Descriptor &string, } } -void RTNAME(Repeat)(Descriptor &result, const Descriptor &string, +void RTDEF(Repeat)(Descriptor &result, const Descriptor &string, std::int64_t ncopies, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (ncopies < 0) { @@ -835,7 +821,7 @@ void RTNAME(Repeat)(Descriptor &result, const Descriptor &string, } } -void RTNAME(Trim)(Descriptor &result, const Descriptor &string, +void RTDEF(Trim)(Descriptor &result, const Descriptor &string, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; std::size_t resultBytes{0}; @@ -864,20 +850,20 @@ void RTNAME(Trim)(Descriptor &result, const Descriptor &string, std::memcpy(result.OffsetElement(), string.OffsetElement(), resultBytes); } -std::size_t RTNAME(Verify1)(const char *x, std::size_t xLen, const char *set, +std::size_t RTDEF(Verify1)(const char *x, std::size_t xLen, const char *set, std::size_t setLen, bool back) { return ScanVerify(x, xLen, set, setLen, back); } -std::size_t RTNAME(Verify2)(const char16_t *x, std::size_t xLen, +std::size_t RTDEF(Verify2)(const char16_t *x, std::size_t xLen, const char16_t *set, std::size_t setLen, bool back) { return ScanVerify(x, xLen, set, setLen, back); } -std::size_t RTNAME(Verify4)(const char32_t *x, std::size_t xLen, +std::size_t RTDEF(Verify4)(const char32_t *x, std::size_t xLen, const char32_t *set, std::size_t setLen, bool back) { return ScanVerify(x, xLen, set, setLen, back); } -void RTNAME(Verify)(Descriptor &result, const Descriptor &string, +void RTDEF(Verify)(Descriptor &result, const Descriptor &string, const Descriptor &set, const Descriptor *back, int kind, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; @@ -900,14 +886,16 @@ void RTNAME(Verify)(Descriptor &result, const Descriptor &string, } } -void RTNAME(CharacterMax)(Descriptor &accumulator, const Descriptor &x, +void RTDEF(CharacterMax)(Descriptor &accumulator, const Descriptor &x, const char *sourceFile, int sourceLine) { MaxMin(accumulator, x, sourceFile, sourceLine); } -void RTNAME(CharacterMin)(Descriptor &accumulator, const Descriptor &x, +void RTDEF(CharacterMin)(Descriptor &accumulator, const Descriptor &x, const char *sourceFile, int sourceLine) { MaxMin(accumulator, x, sourceFile, sourceLine); } + +RT_EXT_API_GROUP_END } } // namespace Fortran::runtime diff --git a/flang/runtime/connection.cpp b/flang/runtime/connection.cpp index 0abacd7995b4714d2aa8e8777b67006ef090db6e..91ac9a0e14e47bed0c32f6105a95614d16a5e123 100644 --- a/flang/runtime/connection.cpp +++ b/flang/runtime/connection.cpp @@ -46,13 +46,15 @@ SavedPosition::SavedPosition(IoStatementState &io) : io_{io} { } SavedPosition::~SavedPosition() { - ConnectionState &conn{io_.GetConnectionState()}; - while (conn.currentRecordNumber > saved_.currentRecordNumber) { - io_.BackspaceRecord(); + if (!cancelled_) { + ConnectionState &conn{io_.GetConnectionState()}; + while (conn.currentRecordNumber > saved_.currentRecordNumber) { + io_.BackspaceRecord(); + } + conn.leftTabLimit = saved_.leftTabLimit; + conn.furthestPositionInRecord = saved_.furthestPositionInRecord; + conn.positionInRecord = saved_.positionInRecord; + conn.pinnedFrame = saved_.pinnedFrame; } - conn.leftTabLimit = saved_.leftTabLimit; - conn.furthestPositionInRecord = saved_.furthestPositionInRecord; - conn.positionInRecord = saved_.positionInRecord; - conn.pinnedFrame = saved_.pinnedFrame; } } // namespace Fortran::runtime::io diff --git a/flang/runtime/connection.h b/flang/runtime/connection.h index 70c20e17fd01ac8fdabd93f3a53ecbf06c68342b..c9a7566f209881c0b8824143adc6336d030175c5 100644 --- a/flang/runtime/connection.h +++ b/flang/runtime/connection.h @@ -111,10 +111,12 @@ class SavedPosition { public: explicit SavedPosition(IoStatementState &); ~SavedPosition(); + void Cancel() { cancelled_ = true; } private: IoStatementState &io_; ConnectionState saved_; + bool cancelled_{false}; }; } // namespace Fortran::runtime::io diff --git a/flang/runtime/copy.cpp b/flang/runtime/copy.cpp index 71ef2c2f75665bafab5bdc8ea2c363276a10e99d..9e62d1e24a4731a765f98d4444b5a7b2875b43ff 100644 --- a/flang/runtime/copy.cpp +++ b/flang/runtime/copy.cpp @@ -14,8 +14,9 @@ #include namespace Fortran::runtime { +RT_OFFLOAD_API_GROUP_BEGIN -void CopyElement(const Descriptor &to, const SubscriptValue toAt[], +RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[], const Descriptor &from, const SubscriptValue fromAt[], Terminator &terminator) { char *toPtr{to.Element(toAt)}; @@ -48,7 +49,7 @@ void CopyElement(const Descriptor &to, const SubscriptValue toAt[], } } -void CopyArray( +RT_API_ATTRS void CopyArray( const Descriptor &to, const Descriptor &from, Terminator &terminator) { std::size_t elements{to.Elements()}; RUNTIME_CHECK(terminator, elements == from.Elements()); @@ -61,4 +62,6 @@ void CopyArray( from.IncrementSubscripts(fromAt); } } + +RT_OFFLOAD_API_GROUP_END } // namespace Fortran::runtime diff --git a/flang/runtime/derived-api.cpp b/flang/runtime/derived-api.cpp index 39bf0521e73b16ba5b5b4cfaebae214b659ae338..321f50a1edfcfe8f03b420ff256850fa846bf22c 100644 --- a/flang/runtime/derived-api.cpp +++ b/flang/runtime/derived-api.cpp @@ -10,14 +10,16 @@ #include "flang/Runtime/derived-api.h" #include "derived.h" #include "terminator.h" +#include "tools.h" #include "type-info.h" #include "flang/Runtime/descriptor.h" namespace Fortran::runtime { extern "C" { +RT_EXT_API_GROUP_BEGIN -void RTNAME(Initialize)( +void RTDEF(Initialize)( const Descriptor &descriptor, const char *sourceFile, int sourceLine) { if (const DescriptorAddendum * addendum{descriptor.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { @@ -29,7 +31,7 @@ void RTNAME(Initialize)( } } -void RTNAME(Destroy)(const Descriptor &descriptor) { +void RTDEF(Destroy)(const Descriptor &descriptor) { if (const DescriptorAddendum * addendum{descriptor.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { if (!derived->noDestructionNeeded()) { @@ -41,7 +43,7 @@ void RTNAME(Destroy)(const Descriptor &descriptor) { } } -void RTNAME(Finalize)( +void RTDEF(Finalize)( const Descriptor &descriptor, const char *sourceFile, int sourceLine) { if (const DescriptorAddendum * addendum{descriptor.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { @@ -53,7 +55,7 @@ void RTNAME(Finalize)( } } -bool RTNAME(ClassIs)( +bool RTDEF(ClassIs)( const Descriptor &descriptor, const typeInfo::DerivedType &derivedType) { if (const DescriptorAddendum * addendum{descriptor.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { @@ -72,7 +74,8 @@ bool RTNAME(ClassIs)( return false; } -static bool CompareDerivedTypeNames(const Descriptor &a, const Descriptor &b) { +static RT_API_ATTRS bool CompareDerivedTypeNames( + const Descriptor &a, const Descriptor &b) { if (a.raw().version == CFI_VERSION && a.type() == TypeCode{TypeCategory::Character, 1} && a.ElementBytes() > 0 && a.rank() == 0 && a.OffsetElement() != nullptr && @@ -80,18 +83,20 @@ static bool CompareDerivedTypeNames(const Descriptor &a, const Descriptor &b) { b.type() == TypeCode{TypeCategory::Character, 1} && b.ElementBytes() > 0 && b.rank() == 0 && b.OffsetElement() != nullptr && a.ElementBytes() == b.ElementBytes() && - memcmp(a.OffsetElement(), b.OffsetElement(), a.ElementBytes()) == 0) { + Fortran::runtime::memcmp( + a.OffsetElement(), b.OffsetElement(), a.ElementBytes()) == 0) { return true; } return false; } -inline bool CompareDerivedType( +inline RT_API_ATTRS bool CompareDerivedType( const typeInfo::DerivedType *a, const typeInfo::DerivedType *b) { return a == b || CompareDerivedTypeNames(a->name(), b->name()); } -static const typeInfo::DerivedType *GetDerivedType(const Descriptor &desc) { +static const RT_API_ATTRS typeInfo::DerivedType *GetDerivedType( + const Descriptor &desc) { if (const DescriptorAddendum * addendum{desc.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { return derived; @@ -100,7 +105,7 @@ static const typeInfo::DerivedType *GetDerivedType(const Descriptor &desc) { return nullptr; } -bool RTNAME(SameTypeAs)(const Descriptor &a, const Descriptor &b) { +bool RTDEF(SameTypeAs)(const Descriptor &a, const Descriptor &b) { auto aType{a.raw().type}; auto bType{b.raw().type}; if ((aType != CFI_type_struct && aType != CFI_type_other) || @@ -125,7 +130,7 @@ bool RTNAME(SameTypeAs)(const Descriptor &a, const Descriptor &b) { } } -bool RTNAME(ExtendsTypeOf)(const Descriptor &a, const Descriptor &mold) { +bool RTDEF(ExtendsTypeOf)(const Descriptor &a, const Descriptor &mold) { auto aType{a.raw().type}; auto moldType{mold.raw().type}; if ((aType != CFI_type_struct && aType != CFI_type_other) || @@ -152,7 +157,7 @@ bool RTNAME(ExtendsTypeOf)(const Descriptor &a, const Descriptor &mold) { } } -void RTNAME(DestroyWithoutFinalization)(const Descriptor &descriptor) { +void RTDEF(DestroyWithoutFinalization)(const Descriptor &descriptor) { if (const DescriptorAddendum * addendum{descriptor.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { if (!derived->noDestructionNeeded()) { @@ -162,5 +167,6 @@ void RTNAME(DestroyWithoutFinalization)(const Descriptor &descriptor) { } } +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/dot-product.cpp b/flang/runtime/dot-product.cpp index 58382863a5006752be0374312fe80650f716f6d8..977698269bcb46d072e5941d04d956143f6f311a 100644 --- a/flang/runtime/dot-product.cpp +++ b/flang/runtime/dot-product.cpp @@ -21,14 +21,20 @@ namespace Fortran::runtime { // Beware: DOT_PRODUCT of COMPLEX data uses the complex conjugate of the first // argument; MATMUL does not. +// Suppress the warnings about calling __host__-only std::complex operators, +// defined in C++ STD header files, from __device__ code. +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // General accumulator for any type and stride; this is not used for // contiguous numeric vectors. template class Accumulator { public: using Result = AccumulationType; - Accumulator(const Descriptor &x, const Descriptor &y) : x_{x}, y_{y} {} - void AccumulateIndexed(SubscriptValue xAt, SubscriptValue yAt) { + RT_API_ATTRS Accumulator(const Descriptor &x, const Descriptor &y) + : x_{x}, y_{y} {} + RT_API_ATTRS void AccumulateIndexed(SubscriptValue xAt, SubscriptValue yAt) { if constexpr (RCAT == TypeCategory::Logical) { sum_ = sum_ || (IsLogicalElementTrue(x_, &xAt) && IsLogicalElementTrue(y_, &yAt)); @@ -43,7 +49,7 @@ public: } } } - Result GetResult() const { return sum_; } + RT_API_ATTRS Result GetResult() const { return sum_; } private: const Descriptor &x_, &y_; @@ -51,7 +57,7 @@ private: }; template -static inline CppTypeFor DoDotProduct( +static inline RT_API_ATTRS CppTypeFor DoDotProduct( const Descriptor &x, const Descriptor &y, Terminator &terminator) { using Result = CppTypeFor; RUNTIME_CHECK(terminator, x.rank() == 1 && y.rank() == 1); @@ -83,8 +89,14 @@ static inline CppTypeFor DoDotProduct( AccumType accum{}; if constexpr (RCAT == TypeCategory::Complex) { for (SubscriptValue j{0}; j < n; ++j) { - accum += std::conj(static_cast(*xp++)) * + // std::conj() may instantiate its argument twice, + // so xp has to be incremented separately. + // This is a workaround for an alleged bug in clang, + // that shows up as: + // warning: multiple unsequenced modifications to 'xp' + accum += std::conj(static_cast(*xp)) * static_cast(*yp++); + xp++; } } else { for (SubscriptValue j{0}; j < n; ++j) { @@ -105,11 +117,13 @@ static inline CppTypeFor DoDotProduct( return static_cast(accumulator.GetResult()); } +RT_DIAG_POP + template struct DotProduct { using Result = CppTypeFor; template struct DP1 { template struct DP2 { - Result operator()(const Descriptor &x, const Descriptor &y, + RT_API_ATTRS Result operator()(const Descriptor &x, const Descriptor &y, Terminator &terminator) const { if constexpr (constexpr auto resultType{ GetResultType(XCAT, XKIND, YCAT, YKIND)}) { @@ -125,12 +139,12 @@ template struct DotProduct { static_cast(YCAT), YKIND); } }; - Result operator()(const Descriptor &x, const Descriptor &y, + RT_API_ATTRS Result operator()(const Descriptor &x, const Descriptor &y, Terminator &terminator, TypeCategory yCat, int yKind) const { return ApplyType(yCat, yKind, terminator, x, y, terminator); } }; - Result operator()(const Descriptor &x, const Descriptor &y, + RT_API_ATTRS Result operator()(const Descriptor &x, const Descriptor &y, const char *source, int line) const { Terminator terminator{source, line}; if (RCAT != TypeCategory::Logical && x.type() == y.type()) { @@ -148,24 +162,26 @@ template struct DotProduct { }; extern "C" { -CppTypeFor RTNAME(DotProductInteger1)( +RT_EXT_API_GROUP_BEGIN + +CppTypeFor RTDEF(DotProductInteger1)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } -CppTypeFor RTNAME(DotProductInteger2)( +CppTypeFor RTDEF(DotProductInteger2)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } -CppTypeFor RTNAME(DotProductInteger4)( +CppTypeFor RTDEF(DotProductInteger4)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } -CppTypeFor RTNAME(DotProductInteger8)( +CppTypeFor RTDEF(DotProductInteger8)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(DotProductInteger16)( +CppTypeFor RTDEF(DotProductInteger16)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } @@ -173,53 +189,55 @@ CppTypeFor RTNAME(DotProductInteger16)( // TODO: REAL/COMPLEX(2 & 3) // Intermediate results and operations are at least 64 bits -CppTypeFor RTNAME(DotProductReal4)( +CppTypeFor RTDEF(DotProductReal4)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } -CppTypeFor RTNAME(DotProductReal8)( +CppTypeFor RTDEF(DotProductReal8)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(DotProductReal10)( +CppTypeFor RTDEF(DotProductReal10)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(DotProductReal16)( +CppTypeFor RTDEF(DotProductReal16)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } #endif -void RTNAME(CppDotProductComplex4)(CppTypeFor &result, +void RTDEF(CppDotProductComplex4)(CppTypeFor &result, const Descriptor &x, const Descriptor &y, const char *source, int line) { result = DotProduct{}(x, y, source, line); } -void RTNAME(CppDotProductComplex8)(CppTypeFor &result, +void RTDEF(CppDotProductComplex8)(CppTypeFor &result, const Descriptor &x, const Descriptor &y, const char *source, int line) { result = DotProduct{}(x, y, source, line); } #if LDBL_MANT_DIG == 64 -void RTNAME(CppDotProductComplex10)( +void RTDEF(CppDotProductComplex10)( CppTypeFor &result, const Descriptor &x, const Descriptor &y, const char *source, int line) { result = DotProduct{}(x, y, source, line); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -void RTNAME(CppDotProductComplex16)( +void RTDEF(CppDotProductComplex16)( CppTypeFor &result, const Descriptor &x, const Descriptor &y, const char *source, int line) { result = DotProduct{}(x, y, source, line); } #endif -bool RTNAME(DotProductLogical)( +bool RTDEF(DotProductLogical)( const Descriptor &x, const Descriptor &y, const char *source, int line) { return DotProduct{}(x, y, source, line); } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp index 822099b5141b1b4d86f11742d8bd9cd7a9c8d10e..6d4fa588cbf60d065c5c28683a8aff7538091ff4 100644 --- a/flang/runtime/edit-input.cpp +++ b/flang/runtime/edit-input.cpp @@ -21,7 +21,8 @@ namespace Fortran::runtime::io { static inline bool IsCharValueSeparator(const DataEdit &edit, char32_t ch) { char32_t comma{ edit.modes.editingFlags & decimalComma ? char32_t{';'} : char32_t{','}}; - return ch == ' ' || ch == '\t' || ch == '/' || ch == comma; + return ch == ' ' || ch == '\t' || ch == comma || ch == '/' || + (edit.IsNamelist() && (ch == '&' || ch == '$')); } static bool CheckCompleteListDirectedField( @@ -243,10 +244,21 @@ bool EditIntegerInput( if (sign == '-') { value = -value; } - if (any || !io.GetConnectionState().IsAtEOF()) { - std::memcpy(n, &value, kind); // a blank field means zero + if (any || !io.GetIoErrorHandler().InError()) { + // The value is stored in the lower order bits on big endian platform. + // When memcpy, shift the value to the higher order bit. + auto shft{static_cast(sizeof(value.low())) - kind}; + // For kind==8 (i.e. shft==0), the value is stored in low_ in big endian. + if (!isHostLittleEndian && shft >= 0) { + auto l{value.low() << (8 * shft)}; + std::memcpy(n, &l, kind); + } else { + std::memcpy(n, &value, kind); // a blank field means zero + } + return true; + } else { + return false; } - return any; } // Parses a REAL input number from the input source as a normalized @@ -478,6 +490,9 @@ static void RaiseFPExceptions(decimal::ConversionResultFlags flags) { if (flags & decimal::ConversionResultFlags::Overflow) { RAISE(FE_OVERFLOW); } + if (flags & decimal::ConversionResultFlags::Underflow) { + RAISE(FE_UNDERFLOW); + } if (flags & decimal::ConversionResultFlags::Inexact) { RAISE(FE_INEXACT); } @@ -612,48 +627,26 @@ decimal::ConversionToBinaryResult ConvertHexadecimal( fraction <<= 1; --expo; } - // Rounding - bool increase{false}; - switch (rounding) { - case decimal::RoundNearest: // RN & RP - increase = roundingBit && (guardBit | ((int)fraction & 1)); - break; - case decimal::RoundUp: // RU - increase = !isNegative && (roundingBit | guardBit); - break; - case decimal::RoundDown: // RD - increase = isNegative && (roundingBit | guardBit); - break; - case decimal::RoundToZero: // RZ - break; - case decimal::RoundCompatible: // RC - increase = roundingBit != 0; - break; - } - if (increase) { - ++fraction; - if (fraction >> binaryPrecision) { - fraction >>= 1; - ++expo; - } - } } // Package & return result constexpr RawType significandMask{(one << RealType::significandBits) - 1}; + int flags{(roundingBit | guardBit) ? decimal::Inexact : decimal::Exact}; if (!fraction) { expo = 0; } else if (expo == 1 && !(fraction >> (binaryPrecision - 1))) { expo = 0; // subnormal + flags |= decimal::Underflow; } else if (expo >= RealType::maxExponent) { expo = RealType::maxExponent; // +/-Inf fraction = 0; + flags |= decimal::Overflow; } else { fraction &= significandMask; // remove explicit normalization unless x87 } return decimal::ConversionToBinaryResult{ RealType{static_cast(signBit | static_cast(expo) << RealType::significandBits | fraction)}, - (roundingBit | guardBit) ? decimal::Inexact : decimal::Exact}; + static_cast(flags)}; } template @@ -895,6 +888,10 @@ static bool EditListDirectedCharacterInput( case '/': isSep = true; break; + case '&': + case '$': + isSep = edit.IsNamelist(); + break; case ',': isSep = !(edit.modes.editingFlags & decimalComma); break; diff --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp index a4ce0b12f911116b756c6810a1a761c4a0a4e1e5..26e066c85fed392217c090384018581edd7b3c98 100644 --- a/flang/runtime/edit-output.cpp +++ b/flang/runtime/edit-output.cpp @@ -341,11 +341,12 @@ bool RealOutputEditing::EditEorDOutput(const DataEdit &edit) { ConvertToDecimal(significantDigits, edit.modes.round, flags)}; if (IsInfOrNaN(converted.str, static_cast(converted.length))) { return editWidth > 0 && - converted.length > static_cast(editWidth) + converted.length + trailingBlanks_ > + static_cast(editWidth) ? EmitRepeated(io_, '*', editWidth) : EmitPrefix(edit, converted.length, editWidth) && EmitAscii(io_, converted.str, converted.length) && - EmitSuffix(edit); + EmitRepeated(io_, ' ', trailingBlanks_) && EmitSuffix(edit); } if (!IsZero()) { converted.decimalExponent -= scale; @@ -522,8 +523,9 @@ bool RealOutputEditing::EditFOutput(const DataEdit &edit) { zeroesBeforePoint = 1; // "." -> "0." } int totalLength{signLength + digitsBeforePoint + zeroesBeforePoint + - 1 /*'.'*/ + zeroesAfterPoint + digitsAfterPoint + trailingZeroes}; - int width{editWidth > 0 ? editWidth : totalLength}; + 1 /*'.'*/ + zeroesAfterPoint + digitsAfterPoint + trailingZeroes + + trailingBlanks_ /* G editing converted to F */}; + int width{editWidth > 0 || trailingBlanks_ ? editWidth : totalLength}; if (totalLength > width) { return EmitRepeated(io_, '*', width); } @@ -574,8 +576,11 @@ DataEdit RealOutputEditing::EditForGOutput(DataEdit edit) { trailingBlanks_ = 0; if (editWidth > 0) { int expoDigits{edit.expoDigits.value_or(0)}; + // F'2023 13.7.5.2.3 p5: "If 0 <= s <= d, the scale factor has no effect + // and F(w − n).(d − s),n(’b’) editing is used where b is a blank and + // n is 4 for Gw.d editing, e + 2 for Gw.dEe editing if e > 0, and + // 4 for Gw.dE0 editing." trailingBlanks_ = expoDigits > 0 ? expoDigits + 2 : 4; // 'n' - *edit.width = std::max(0, editWidth - trailingBlanks_); } if (edit.digits.has_value()) { *edit.digits = std::max(0, *edit.digits - expo); @@ -649,7 +654,7 @@ auto RealOutputEditing::ConvertToHexadecimal( // x_.binaryPrecision is constant, so / can be used for readability. int shift{x_.binaryPrecision - 4}; typename BinaryFloatingPoint::RawType one{1}; - auto remaining{(one << shift) - one}; + auto remaining{(one << x_.binaryPrecision) - one}; for (int digits{0}; digits < significantDigits; ++digits) { if ((flags & decimal::Minimize) && !(fraction & remaining)) { break; @@ -682,7 +687,8 @@ bool RealOutputEditing::EditEXOutput(const DataEdit &edit) { flags |= decimal::AlwaysSign; } int editWidth{edit.width.value_or(0)}; // 'w' field - if (editWidth == 0 && !edit.digits) { // EX0 (no .d) + if ((editWidth == 0 && !edit.digits) || editDigits == 0) { + // EX0 or EXw.0 flags |= decimal::Minimize; significantDigits = 28; // enough for 128-bit F.P. } diff --git a/flang/runtime/exceptions.cpp b/flang/runtime/exceptions.cpp index 1dbee833884fbc6de9eb254adf4c220ac9a56cd2..dfd3b812e22a13d6901fe5d4ec0ea8146242dcae 100644 --- a/flang/runtime/exceptions.cpp +++ b/flang/runtime/exceptions.cpp @@ -78,10 +78,10 @@ std::int32_t RTNAME(MapException)(int32_t except) { // Verify that the size of ieee_modes_type and ieee_status_type objects from // intrinsic module file __fortran_ieee_exceptions.f90 are large enough to // hold fenv_t object. +// TODO: fenv_t can be way larger than +// sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT +// on some systems, e.g. Solaris, so omit object size comparison for now. // TODO: consider femode_t object size comparison once its more mature. -static_assert( - sizeof(fenv_t) <= sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT, - "increase ieee_status_type size"); } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/extensions.cpp b/flang/runtime/extensions.cpp index b8e9b6eae13205988bdd2f380ee3b07776c72e66..1c025d40b395247d6cf877d65be9f0b107d62803 100644 --- a/flang/runtime/extensions.cpp +++ b/flang/runtime/extensions.cpp @@ -10,13 +10,29 @@ // extensions that will eventually be implemented in Fortran. #include "flang/Runtime/extensions.h" +#include "tools.h" #include "flang/Runtime/command.h" #include "flang/Runtime/descriptor.h" #include "flang/Runtime/io-api.h" +#if _REENTRANT || _POSIX_C_SOURCE >= 199506L +// System is posix-compliant and has getlogin_r +#include +#endif + extern "C" { namespace Fortran::runtime { + +void GetUsernameEnvVar( + const char *envName, std::byte *arg, std::int64_t length) { + Descriptor name{*Descriptor::Create( + 1, std::strlen(envName) + 1, const_cast(envName), 0)}; + Descriptor value{*Descriptor::Create(1, length, arg, 0)}; + + RTNAME(GetEnvVariable) + (name, &value, nullptr, false, nullptr, __FILE__, __LINE__); +} namespace io { // SUBROUTINE FLUSH(N) // FLUSH N @@ -37,5 +53,28 @@ void FORTRAN_PROCEDURE_NAME(getarg)( (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } + +// CALL GETLOG(USRNAME) +void FORTRAN_PROCEDURE_NAME(getlog)(std::byte *arg, std::int64_t length) { +#if _REENTRANT || _POSIX_C_SOURCE >= 199506L + const int nameMaxLen{LOGIN_NAME_MAX + 1}; + char str[nameMaxLen]; + + int error{getlogin_r(str, nameMaxLen)}; + if (error == 0) { + // no error: find first \0 in string then pad from there + CopyAndPad(reinterpret_cast(arg), str, length, std::strlen(str)); + } else { + // error occur: get username from environment variable + GetUsernameEnvVar("LOGNAME", arg, length); + } +#elif _WIN32 + // Get username from environment to avoid link to Advapi32.lib + GetUsernameEnvVar("USERNAME", arg, length); +#else + GetUsernameEnvVar("LOGNAME", arg, length); +#endif +} + } // namespace Fortran::runtime } // extern "C" diff --git a/flang/runtime/extrema.cpp b/flang/runtime/extrema.cpp index 70b2c4d3d735a176450127882162b5aa47062c91..edb5d5f47a5acfa54d860e14b9187e3d3000cd4a 100644 --- a/flang/runtime/extrema.cpp +++ b/flang/runtime/extrema.cpp @@ -26,8 +26,8 @@ namespace Fortran::runtime { template struct NumericCompare { using Type = T; - explicit NumericCompare(std::size_t /*elemLen; ignored*/) {} - bool operator()(const T &value, const T &previous) const { + explicit RT_API_ATTRS NumericCompare(std::size_t /*elemLen; ignored*/) {} + RT_API_ATTRS bool operator()(const T &value, const T &previous) const { if (value == previous) { return BACK; } else if constexpr (IS_MAX) { @@ -41,9 +41,9 @@ template struct NumericCompare { template class CharacterCompare { public: using Type = T; - explicit CharacterCompare(std::size_t elemLen) + explicit RT_API_ATTRS CharacterCompare(std::size_t elemLen) : chars_{elemLen / sizeof(T)} {} - bool operator()(const T &value, const T &previous) const { + RT_API_ATTRS bool operator()(const T &value, const T &previous) const { int cmp{CharacterScalarCompare(&value, &previous, chars_, chars_)}; if (cmp == 0) { return BACK; @@ -61,19 +61,20 @@ private: template class ExtremumLocAccumulator { public: using Type = typename COMPARE::Type; - ExtremumLocAccumulator(const Descriptor &array) + RT_API_ATTRS ExtremumLocAccumulator(const Descriptor &array) : array_{array}, argRank_{array.rank()}, compare_{array.ElementBytes()} { Reinitialize(); } - void Reinitialize() { + RT_API_ATTRS void Reinitialize() { // per standard: result indices are all zero if no data for (int j{0}; j < argRank_; ++j) { extremumLoc_[j] = 0; } previous_ = nullptr; } - int argRank() const { return argRank_; } - template void GetResult(A *p, int zeroBasedDim = -1) { + RT_API_ATTRS int argRank() const { return argRank_; } + template + RT_API_ATTRS void GetResult(A *p, int zeroBasedDim = -1) { if (zeroBasedDim >= 0) { *p = extremumLoc_[zeroBasedDim] - array_.GetDimension(zeroBasedDim).LowerBound() + 1; @@ -83,7 +84,8 @@ public: } } } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { const auto &value{*array_.Element(at)}; if (!previous_ || compare_(value, *previous_)) { previous_ = &value; @@ -103,8 +105,8 @@ private: }; template -static void LocationHelper(const char *intrinsic, Descriptor &result, - const Descriptor &x, int kind, const Descriptor *mask, +static RT_API_ATTRS void LocationHelper(const char *intrinsic, + Descriptor &result, const Descriptor &x, int kind, const Descriptor *mask, Terminator &terminator) { ACCUMULATOR accumulator{x}; DoTotalReduction(x, 0, mask, accumulator, intrinsic, terminator); @@ -114,9 +116,9 @@ static void LocationHelper(const char *intrinsic, Descriptor &result, template class COMPARE> -inline void DoMaxOrMinLoc(const char *intrinsic, Descriptor &result, - const Descriptor &x, int kind, const char *source, int line, - const Descriptor *mask, bool back) { +inline RT_API_ATTRS void DoMaxOrMinLoc(const char *intrinsic, + Descriptor &result, const Descriptor &x, int kind, const char *source, + int line, const Descriptor *mask, bool back) { using CppType = CppTypeFor; Terminator terminator{source, line}; if (back) { @@ -130,7 +132,7 @@ inline void DoMaxOrMinLoc(const char *intrinsic, Descriptor &result, template struct CharacterMaxOrMinLocHelper { template struct Functor { - void operator()(const char *intrinsic, Descriptor &result, + RT_API_ATTRS void operator()(const char *intrinsic, Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) const { DoMaxOrMinLoc( @@ -140,9 +142,9 @@ template struct CharacterMaxOrMinLocHelper { }; template -inline void CharacterMaxOrMinLoc(const char *intrinsic, Descriptor &result, - const Descriptor &x, int kind, const char *source, int line, - const Descriptor *mask, bool back) { +inline RT_API_ATTRS void CharacterMaxOrMinLoc(const char *intrinsic, + Descriptor &result, const Descriptor &x, int kind, const char *source, + int line, const Descriptor *mask, bool back) { int rank{x.rank()}; SubscriptValue extent[1]{rank}; result.Establish(TypeCategory::Integer, kind, nullptr, 1, extent, @@ -169,9 +171,9 @@ inline void CharacterMaxOrMinLoc(const char *intrinsic, Descriptor &result, } template -inline void TotalNumericMaxOrMinLoc(const char *intrinsic, Descriptor &result, - const Descriptor &x, int kind, const char *source, int line, - const Descriptor *mask, bool back) { +inline RT_API_ATTRS void TotalNumericMaxOrMinLoc(const char *intrinsic, + Descriptor &result, const Descriptor &x, int kind, const char *source, + int line, const Descriptor *mask, bool back) { int rank{x.rank()}; SubscriptValue extent[1]{rank}; result.Establish(TypeCategory::Integer, kind, nullptr, 1, extent, @@ -189,125 +191,129 @@ inline void TotalNumericMaxOrMinLoc(const char *intrinsic, Descriptor &result, } extern "C" { -void RTNAME(MaxlocCharacter)(Descriptor &result, const Descriptor &x, int kind, +RT_EXT_API_GROUP_BEGIN + +void RTDEF(MaxlocCharacter)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { CharacterMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MaxlocInteger1)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocInteger1)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MaxlocInteger2)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocInteger2)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MaxlocInteger4)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocInteger4)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MaxlocInteger8)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocInteger8)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } #ifdef __SIZEOF_INT128__ -void RTNAME(MaxlocInteger16)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocInteger16)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } #endif -void RTNAME(MaxlocReal4)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocReal4)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MaxlocReal8)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocReal8)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } #if LDBL_MANT_DIG == 64 -void RTNAME(MaxlocReal10)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocReal10)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -void RTNAME(MaxlocReal16)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MaxlocReal16)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MAXLOC", result, x, kind, source, line, mask, back); } #endif -void RTNAME(MinlocCharacter)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocCharacter)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { CharacterMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MinlocInteger1)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocInteger1)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MinlocInteger2)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocInteger2)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MinlocInteger4)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocInteger4)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MinlocInteger8)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocInteger8)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } #ifdef __SIZEOF_INT128__ -void RTNAME(MinlocInteger16)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocInteger16)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } #endif -void RTNAME(MinlocReal4)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocReal4)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } -void RTNAME(MinlocReal8)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocReal8)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } #if LDBL_MANT_DIG == 64 -void RTNAME(MinlocReal10)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocReal10)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -void RTNAME(MinlocReal16)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocReal16)(Descriptor &result, const Descriptor &x, int kind, const char *source, int line, const Descriptor *mask, bool back) { TotalNumericMaxOrMinLoc( "MINLOC", result, x, kind, source, line, mask, back); } #endif + +RT_EXT_API_GROUP_END } // extern "C" // MAXLOC/MINLOC with DIM= template class COMPARE, bool BACK> -static void DoPartialMaxOrMinLocDirection(const char *intrinsic, +static RT_API_ATTRS void DoPartialMaxOrMinLocDirection(const char *intrinsic, Descriptor &result, const Descriptor &x, int kind, int dim, const Descriptor *mask, Terminator &terminator) { using CppType = CppTypeFor; @@ -320,9 +326,9 @@ static void DoPartialMaxOrMinLocDirection(const char *intrinsic, template class COMPARE> -inline void DoPartialMaxOrMinLoc(const char *intrinsic, Descriptor &result, - const Descriptor &x, int kind, int dim, const Descriptor *mask, bool back, - Terminator &terminator) { +inline RT_API_ATTRS void DoPartialMaxOrMinLoc(const char *intrinsic, + Descriptor &result, const Descriptor &x, int kind, int dim, + const Descriptor *mask, bool back, Terminator &terminator) { if (back) { DoPartialMaxOrMinLocDirection( intrinsic, result, x, kind, dim, mask, terminator); @@ -336,7 +342,7 @@ template class COMPARE> struct DoPartialMaxOrMinLocHelper { template struct Functor { - void operator()(const char *intrinsic, Descriptor &result, + RT_API_ATTRS void operator()(const char *intrinsic, Descriptor &result, const Descriptor &x, int kind, int dim, const Descriptor *mask, bool back, Terminator &terminator) const { DoPartialMaxOrMinLoc( @@ -346,9 +352,9 @@ struct DoPartialMaxOrMinLocHelper { }; template -inline void TypedPartialMaxOrMinLoc(const char *intrinsic, Descriptor &result, - const Descriptor &x, int kind, int dim, const char *source, int line, - const Descriptor *mask, bool back) { +inline RT_API_ATTRS void TypedPartialMaxOrMinLoc(const char *intrinsic, + Descriptor &result, const Descriptor &x, int kind, int dim, + const char *source, int line, const Descriptor *mask, bool back) { Terminator terminator{source, line}; CheckIntegerKind(terminator, kind, intrinsic); auto catKind{x.type().GetCategoryAndKind()}; @@ -398,16 +404,20 @@ inline void TypedPartialMaxOrMinLoc(const char *intrinsic, Descriptor &result, } extern "C" { -void RTNAME(MaxlocDim)(Descriptor &result, const Descriptor &x, int kind, +RT_EXT_API_GROUP_BEGIN + +void RTDEF(MaxlocDim)(Descriptor &result, const Descriptor &x, int kind, int dim, const char *source, int line, const Descriptor *mask, bool back) { TypedPartialMaxOrMinLoc( "MAXLOC", result, x, kind, dim, source, line, mask, back); } -void RTNAME(MinlocDim)(Descriptor &result, const Descriptor &x, int kind, +void RTDEF(MinlocDim)(Descriptor &result, const Descriptor &x, int kind, int dim, const char *source, int line, const Descriptor *mask, bool back) { TypedPartialMaxOrMinLoc( "MINLOC", result, x, kind, dim, source, line, mask, back); } + +RT_EXT_API_GROUP_END } // extern "C" // MAXVAL and MINVAL @@ -415,7 +425,7 @@ void RTNAME(MinlocDim)(Descriptor &result, const Descriptor &x, int kind, template struct MaxOrMinIdentity { using Type = CppTypeFor; - static constexpr Type Value() { + static constexpr RT_API_ATTRS Type Value() { return IS_MAXVAL ? std::numeric_limits::lowest() : std::numeric_limits::max(); } @@ -425,7 +435,7 @@ struct MaxOrMinIdentity { template struct MaxOrMinIdentity { using Type = CppTypeFor; - static constexpr Type Value() { + static constexpr RT_API_ATTRS Type Value() { return IS_MAXVAL ? Type{1} << 127 : ~Type{0} >> 1; } }; @@ -444,7 +454,7 @@ struct MaxOrMinIdentity, __float128>>> { using Type = __float128; - static Type Value() { + static RT_API_ATTRS Type Value() { // Create a buffer to store binary representation of __float128 constant. constexpr std::size_t alignment = std::max(alignof(Type), alignof(std::uint64_t)); @@ -472,15 +482,16 @@ template class NumericExtremumAccumulator { public: using Type = CppTypeFor; - explicit NumericExtremumAccumulator(const Descriptor &array) + explicit RT_API_ATTRS NumericExtremumAccumulator(const Descriptor &array) : array_{array} {} - void Reinitialize() { + RT_API_ATTRS void Reinitialize() { extremum_ = MaxOrMinIdentity::Value(); } - template void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { + template + RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { *p = extremum_; } - bool Accumulate(Type x) { + RT_API_ATTRS bool Accumulate(Type x) { if constexpr (IS_MAXVAL) { if (x > extremum_) { extremum_ = x; @@ -490,7 +501,8 @@ public: } return true; } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { return Accumulate(*array_.Element(at)); } @@ -500,16 +512,17 @@ private: }; template -inline CppTypeFor TotalNumericMaxOrMin(const Descriptor &x, - const char *source, int line, int dim, const Descriptor *mask, - const char *intrinsic) { +inline RT_API_ATTRS CppTypeFor TotalNumericMaxOrMin( + const Descriptor &x, const char *source, int line, int dim, + const Descriptor *mask, const char *intrinsic) { return GetTotalReduction(x, source, line, dim, mask, NumericExtremumAccumulator{x}, intrinsic); } template -static void DoMaxMinNorm2(Descriptor &result, const Descriptor &x, int dim, - const Descriptor *mask, const char *intrinsic, Terminator &terminator) { +static RT_API_ATTRS void DoMaxMinNorm2(Descriptor &result, const Descriptor &x, + int dim, const Descriptor *mask, const char *intrinsic, + Terminator &terminator) { using Type = CppTypeFor; ACCUMULATOR accumulator{x}; if (dim == 0 || x.rank() == 1) { @@ -537,8 +550,8 @@ static void DoMaxMinNorm2(Descriptor &result, const Descriptor &x, int dim, template struct MaxOrMinHelper { template struct Functor { - void operator()(Descriptor &result, const Descriptor &x, int dim, - const Descriptor *mask, const char *intrinsic, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, + int dim, const Descriptor *mask, const char *intrinsic, Terminator &terminator) const { DoMaxMinNorm2>( @@ -548,9 +561,9 @@ template struct MaxOrMinHelper { }; template -inline void NumericMaxOrMin(Descriptor &result, const Descriptor &x, int dim, - const char *source, int line, const Descriptor *mask, - const char *intrinsic) { +inline RT_API_ATTRS void NumericMaxOrMin(Descriptor &result, + const Descriptor &x, int dim, const char *source, int line, + const Descriptor *mask, const char *intrinsic) { Terminator terminator{source, line}; auto type{x.type().GetCategoryAndKind()}; RUNTIME_CHECK(terminator, type); @@ -574,10 +587,11 @@ inline void NumericMaxOrMin(Descriptor &result, const Descriptor &x, int dim, template class CharacterExtremumAccumulator { public: using Type = CppTypeFor; - explicit CharacterExtremumAccumulator(const Descriptor &array) + explicit RT_API_ATTRS CharacterExtremumAccumulator(const Descriptor &array) : array_{array}, charLen_{array_.ElementBytes() / KIND} {} - void Reinitialize() { extremum_ = nullptr; } - template void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { + RT_API_ATTRS void Reinitialize() { extremum_ = nullptr; } + template + RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { static_assert(std::is_same_v); std::size_t byteSize{array_.ElementBytes()}; if (extremum_) { @@ -589,7 +603,7 @@ public: std::memset(p, IS_MAXVAL ? 0 : KIND == 1 ? 127 : 255, byteSize); } } - bool Accumulate(const Type *x) { + RT_API_ATTRS bool Accumulate(const Type *x) { if (!extremum_) { extremum_ = x; } else { @@ -600,7 +614,8 @@ public: } return true; } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { return Accumulate(array_.Element(at)); } @@ -612,8 +627,8 @@ private: template struct CharacterMaxOrMinHelper { template struct Functor { - void operator()(Descriptor &result, const Descriptor &x, int dim, - const Descriptor *mask, const char *intrinsic, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, + int dim, const Descriptor *mask, const char *intrinsic, Terminator &terminator) const { DoMaxMinNorm2>( @@ -623,9 +638,9 @@ template struct CharacterMaxOrMinHelper { }; template -inline void CharacterMaxOrMin(Descriptor &result, const Descriptor &x, int dim, - const char *source, int line, const Descriptor *mask, - const char *intrinsic) { +inline RT_API_ATTRS void CharacterMaxOrMin(Descriptor &result, + const Descriptor &x, int dim, const char *source, int line, + const Descriptor *mask, const char *intrinsic) { Terminator terminator{source, line}; auto type{x.type().GetCategoryAndKind()}; RUNTIME_CHECK(terminator, type && type->first == TypeCategory::Character); @@ -635,28 +650,30 @@ inline void CharacterMaxOrMin(Descriptor &result, const Descriptor &x, int dim, } extern "C" { -CppTypeFor RTNAME(MaxvalInteger1)(const Descriptor &x, +RT_EXT_API_GROUP_BEGIN + +CppTypeFor RTDEF(MaxvalInteger1)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } -CppTypeFor RTNAME(MaxvalInteger2)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalInteger2)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } -CppTypeFor RTNAME(MaxvalInteger4)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalInteger4)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } -CppTypeFor RTNAME(MaxvalInteger8)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalInteger8)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(MaxvalInteger16)( +CppTypeFor RTDEF(MaxvalInteger16)( const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( @@ -665,58 +682,58 @@ CppTypeFor RTNAME(MaxvalInteger16)( #endif // TODO: REAL(2 & 3) -CppTypeFor RTNAME(MaxvalReal4)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalReal4)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } -CppTypeFor RTNAME(MaxvalReal8)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalReal8)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(MaxvalReal10)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalReal10)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(MaxvalReal16)(const Descriptor &x, +CppTypeFor RTDEF(MaxvalReal16)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MAXVAL"); } #endif -void RTNAME(MaxvalCharacter)(Descriptor &result, const Descriptor &x, +void RTDEF(MaxvalCharacter)(Descriptor &result, const Descriptor &x, const char *source, int line, const Descriptor *mask) { CharacterMaxOrMin(result, x, 0, source, line, mask, "MAXVAL"); } -CppTypeFor RTNAME(MinvalInteger1)(const Descriptor &x, +CppTypeFor RTDEF(MinvalInteger1)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } -CppTypeFor RTNAME(MinvalInteger2)(const Descriptor &x, +CppTypeFor RTDEF(MinvalInteger2)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } -CppTypeFor RTNAME(MinvalInteger4)(const Descriptor &x, +CppTypeFor RTDEF(MinvalInteger4)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } -CppTypeFor RTNAME(MinvalInteger8)(const Descriptor &x, +CppTypeFor RTDEF(MinvalInteger8)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(MinvalInteger16)( +CppTypeFor RTDEF(MinvalInteger16)( const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( @@ -725,37 +742,37 @@ CppTypeFor RTNAME(MinvalInteger16)( #endif // TODO: REAL(2 & 3) -CppTypeFor RTNAME(MinvalReal4)(const Descriptor &x, +CppTypeFor RTDEF(MinvalReal4)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } -CppTypeFor RTNAME(MinvalReal8)(const Descriptor &x, +CppTypeFor RTDEF(MinvalReal8)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(MinvalReal10)(const Descriptor &x, +CppTypeFor RTDEF(MinvalReal10)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(MinvalReal16)(const Descriptor &x, +CppTypeFor RTDEF(MinvalReal16)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return TotalNumericMaxOrMin( x, source, line, dim, mask, "MINVAL"); } #endif -void RTNAME(MinvalCharacter)(Descriptor &result, const Descriptor &x, +void RTDEF(MinvalCharacter)(Descriptor &result, const Descriptor &x, const char *source, int line, const Descriptor *mask) { CharacterMaxOrMin(result, x, 0, source, line, mask, "MINVAL"); } -void RTNAME(MaxvalDim)(Descriptor &result, const Descriptor &x, int dim, +void RTDEF(MaxvalDim)(Descriptor &result, const Descriptor &x, int dim, const char *source, int line, const Descriptor *mask) { if (x.type().IsCharacter()) { CharacterMaxOrMin(result, x, dim, source, line, mask, "MAXVAL"); @@ -763,7 +780,7 @@ void RTNAME(MaxvalDim)(Descriptor &result, const Descriptor &x, int dim, NumericMaxOrMin(result, x, dim, source, line, mask, "MAXVAL"); } } -void RTNAME(MinvalDim)(Descriptor &result, const Descriptor &x, int dim, +void RTDEF(MinvalDim)(Descriptor &result, const Descriptor &x, int dim, const char *source, int line, const Descriptor *mask) { if (x.type().IsCharacter()) { CharacterMaxOrMin(result, x, dim, source, line, mask, "MINVAL"); @@ -771,33 +788,42 @@ void RTNAME(MinvalDim)(Descriptor &result, const Descriptor &x, int dim, NumericMaxOrMin(result, x, dim, source, line, mask, "MINVAL"); } } + +RT_EXT_API_GROUP_END } // extern "C" // NORM2 -template class Norm2Accumulator { -public: - using Type = CppTypeFor; - // Use at least double precision for accumulators. - // Don't use __float128, it doesn't work with abs() or sqrt() yet. - static constexpr int largestLDKind { +RT_VAR_GROUP_BEGIN + +// Use at least double precision for accumulators. +// Don't use __float128, it doesn't work with abs() or sqrt() yet. +static constexpr RT_CONST_VAR_ATTRS int largestLDKind { #if LDBL_MANT_DIG == 113 - 16 + 16 #elif LDBL_MANT_DIG == 64 - 10 + 10 #else - 8 + 8 #endif - }; +}; + +RT_VAR_GROUP_END + +template class Norm2Accumulator { +public: + using Type = CppTypeFor; using AccumType = CppTypeFor; - explicit Norm2Accumulator(const Descriptor &array) : array_{array} {} - void Reinitialize() { max_ = sum_ = 0; } - template void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { + explicit RT_API_ATTRS Norm2Accumulator(const Descriptor &array) + : array_{array} {} + RT_API_ATTRS void Reinitialize() { max_ = sum_ = 0; } + template + RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { // m * sqrt(1 + sum((others(:)/m)**2)) *p = static_cast(max_ * std::sqrt(1 + sum_)); } - bool Accumulate(Type x) { + RT_API_ATTRS bool Accumulate(Type x) { auto absX{std::abs(static_cast(x))}; if (!max_) { max_ = absX; @@ -813,7 +839,8 @@ public: } return true; } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { return Accumulate(*array_.Element(at)); } @@ -824,7 +851,7 @@ private: }; template struct Norm2Helper { - void operator()(Descriptor &result, const Descriptor &x, int dim, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, int dim, const Descriptor *mask, Terminator &terminator) const { DoMaxMinNorm2>( result, x, dim, mask, "NORM2", terminator); @@ -832,33 +859,35 @@ template struct Norm2Helper { }; extern "C" { +RT_EXT_API_GROUP_BEGIN + // TODO: REAL(2 & 3) -CppTypeFor RTNAME(Norm2_4)( +CppTypeFor RTDEF(Norm2_4)( const Descriptor &x, const char *source, int line, int dim) { return GetTotalReduction( x, source, line, dim, nullptr, Norm2Accumulator<4>{x}, "NORM2"); } -CppTypeFor RTNAME(Norm2_8)( +CppTypeFor RTDEF(Norm2_8)( const Descriptor &x, const char *source, int line, int dim) { return GetTotalReduction( x, source, line, dim, nullptr, Norm2Accumulator<8>{x}, "NORM2"); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Norm2_10)( +CppTypeFor RTDEF(Norm2_10)( const Descriptor &x, const char *source, int line, int dim) { return GetTotalReduction( x, source, line, dim, nullptr, Norm2Accumulator<10>{x}, "NORM2"); } #endif #if LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Norm2_16)( +CppTypeFor RTDEF(Norm2_16)( const Descriptor &x, const char *source, int line, int dim) { return GetTotalReduction( x, source, line, dim, nullptr, Norm2Accumulator<16>{x}, "NORM2"); } #endif -void RTNAME(Norm2Dim)(Descriptor &result, const Descriptor &x, int dim, +void RTDEF(Norm2Dim)(Descriptor &result, const Descriptor &x, int dim, const char *source, int line) { Terminator terminator{source, line}; auto type{x.type().GetCategoryAndKind()}; @@ -870,5 +899,7 @@ void RTNAME(Norm2Dim)(Descriptor &result, const Descriptor &x, int dim, terminator.Crash("NORM2: bad type code %d", x.type().raw()); } } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/findloc.cpp b/flang/runtime/findloc.cpp index 339e0c75f05fe11a7590affff5c93bdf6263ce17..674a21ae50b853e9180d3eea8682496aca89cc78 100644 --- a/flang/runtime/findloc.cpp +++ b/flang/runtime/findloc.cpp @@ -21,8 +21,8 @@ template struct Equality { using Type1 = CppTypeFor; using Type2 = CppTypeFor; - bool operator()(const Descriptor &array, const SubscriptValue at[], - const Descriptor &target) const { + RT_API_ATTRS bool operator()(const Descriptor &array, + const SubscriptValue at[], const Descriptor &target) const { return *array.Element(at) == *target.OffsetElement(); } }; @@ -31,8 +31,8 @@ template struct Equality { using Type1 = CppTypeFor; using Type2 = CppTypeFor; - bool operator()(const Descriptor &array, const SubscriptValue at[], - const Descriptor &target) const { + RT_API_ATTRS bool operator()(const Descriptor &array, + const SubscriptValue at[], const Descriptor &target) const { const Type1 &xz{*array.Element(at)}; const Type2 &tz{*target.OffsetElement()}; return xz.real() == tz.real() && xz.imag() == tz.imag(); @@ -43,8 +43,8 @@ template struct Equality { using Type1 = CppTypeFor; using Type2 = CppTypeFor; - bool operator()(const Descriptor &array, const SubscriptValue at[], - const Descriptor &target) const { + RT_API_ATTRS bool operator()(const Descriptor &array, + const SubscriptValue at[], const Descriptor &target) const { const Type1 &z{*array.Element(at)}; return z.imag() == 0 && z.real() == *target.OffsetElement(); } @@ -54,8 +54,8 @@ template struct Equality { using Type1 = CppTypeFor; using Type2 = CppTypeFor; - bool operator()(const Descriptor &array, const SubscriptValue at[], - const Descriptor &target) const { + RT_API_ATTRS bool operator()(const Descriptor &array, + const SubscriptValue at[], const Descriptor &target) const { const Type2 &z{*target.OffsetElement()}; return *array.Element(at) == z.real() && z.imag() == 0; } @@ -63,8 +63,8 @@ struct Equality { template struct CharacterEquality { using Type = CppTypeFor; - bool operator()(const Descriptor &array, const SubscriptValue at[], - const Descriptor &target) const { + RT_API_ATTRS bool operator()(const Descriptor &array, + const SubscriptValue at[], const Descriptor &target) const { return CharacterScalarCompare(array.Element(at), target.OffsetElement(), array.ElementBytes() / static_cast(KIND), @@ -73,8 +73,8 @@ template struct CharacterEquality { }; struct LogicalEquivalence { - bool operator()(const Descriptor &array, const SubscriptValue at[], - const Descriptor &target) const { + RT_API_ATTRS bool operator()(const Descriptor &array, + const SubscriptValue at[], const Descriptor &target) const { return IsLogicalElementTrue(array, at) == IsLogicalElementTrue(target, at /*ignored*/); } @@ -82,29 +82,31 @@ struct LogicalEquivalence { template class LocationAccumulator { public: - LocationAccumulator( + RT_API_ATTRS LocationAccumulator( const Descriptor &array, const Descriptor &target, bool back) - : array_{array}, target_{target}, back_{back} { - Reinitialize(); - } - void Reinitialize() { - // per standard: result indices are all zero if no data - for (int j{0}; j < rank_; ++j) { - location_[j] = 0; - } - } - template void GetResult(A *p, int zeroBasedDim = -1) { + : array_{array}, target_{target}, back_{back} {} + RT_API_ATTRS void Reinitialize() { gotAnything_ = false; } + template + RT_API_ATTRS void GetResult(A *p, int zeroBasedDim = -1) { if (zeroBasedDim >= 0) { - *p = location_[zeroBasedDim] - - array_.GetDimension(zeroBasedDim).LowerBound() + 1; - } else { + *p = gotAnything_ ? location_[zeroBasedDim] - + array_.GetDimension(zeroBasedDim).LowerBound() + 1 + : 0; + } else if (gotAnything_) { for (int j{0}; j < rank_; ++j) { p[j] = location_[j] - array_.GetDimension(j).LowerBound() + 1; } + } else { + // no unmasked hits? result is all zeroes + for (int j{0}; j < rank_; ++j) { + p[j] = 0; + } } } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { if (equality_(array_, at, target_)) { + gotAnything_ = true; for (int j{0}; j < rank_; ++j) { location_[j] = at[j]; } @@ -119,6 +121,7 @@ private: const Descriptor &target_; const bool back_{false}; const int rank_{array_.rank()}; + bool gotAnything_{false}; SubscriptValue location_[maxRank]; const EQUALITY equality_{}; }; @@ -126,7 +129,7 @@ private: template struct TotalNumericFindlocHelper { template struct Functor { - void operator()(Descriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, const Descriptor &target, int kind, int dim, const Descriptor *mask, bool back, Terminator &terminator) const { using Eq = Equality; @@ -144,9 +147,10 @@ template struct NumericFindlocHelper { template struct Functor { - void operator()(TypeCategory targetCat, int targetKind, Descriptor &result, - const Descriptor &x, const Descriptor &target, int kind, int dim, - const Descriptor *mask, bool back, Terminator &terminator) const { + RT_API_ATTRS void operator()(TypeCategory targetCat, int targetKind, + Descriptor &result, const Descriptor &x, const Descriptor &target, + int kind, int dim, const Descriptor *mask, bool back, + Terminator &terminator) const { switch (targetCat) { case TypeCategory::Integer: ApplyIntegerKind< @@ -176,7 +180,7 @@ struct NumericFindlocHelper { }; template struct CharacterFindlocHelper { - void operator()(Descriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, const Descriptor &target, int kind, const Descriptor *mask, bool back, Terminator &terminator) { using Accumulator = LocationAccumulator>; @@ -187,9 +191,9 @@ template struct CharacterFindlocHelper { } }; -static void LogicalFindlocHelper(Descriptor &result, const Descriptor &x, - const Descriptor &target, int kind, const Descriptor *mask, bool back, - Terminator &terminator) { +static RT_API_ATTRS void LogicalFindlocHelper(Descriptor &result, + const Descriptor &x, const Descriptor &target, int kind, + const Descriptor *mask, bool back, Terminator &terminator) { using Accumulator = LocationAccumulator; Accumulator accumulator{x, target, back}; DoTotalReduction(x, 0, mask, accumulator, "FINDLOC", terminator); @@ -198,7 +202,9 @@ static void LogicalFindlocHelper(Descriptor &result, const Descriptor &x, } extern "C" { -void RTNAME(Findloc)(Descriptor &result, const Descriptor &x, +RT_EXT_API_GROUP_BEGIN + +void RTDEF(Findloc)(Descriptor &result, const Descriptor &x, const Descriptor &target, int kind, const char *source, int line, const Descriptor *mask, bool back) { int rank{x.rank()}; @@ -250,6 +256,8 @@ void RTNAME(Findloc)(Descriptor &result, const Descriptor &x, "FINDLOC: bad data type code (%d) for array", x.type().raw()); } } + +RT_EXT_API_GROUP_END } // extern "C" // FINDLOC with DIM= @@ -257,7 +265,7 @@ void RTNAME(Findloc)(Descriptor &result, const Descriptor &x, template struct PartialNumericFindlocHelper { template struct Functor { - void operator()(Descriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, const Descriptor &target, int kind, int dim, const Descriptor *mask, bool back, Terminator &terminator) const { using Eq = Equality; @@ -271,7 +279,7 @@ struct PartialNumericFindlocHelper { }; template struct PartialCharacterFindlocHelper { - void operator()(Descriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, const Descriptor &target, int kind, int dim, const Descriptor *mask, bool back, Terminator &terminator) { using Accumulator = LocationAccumulator>; @@ -282,9 +290,9 @@ template struct PartialCharacterFindlocHelper { } }; -static void PartialLogicalFindlocHelper(Descriptor &result, const Descriptor &x, - const Descriptor &target, int kind, int dim, const Descriptor *mask, - bool back, Terminator &terminator) { +static RT_API_ATTRS void PartialLogicalFindlocHelper(Descriptor &result, + const Descriptor &x, const Descriptor &target, int kind, int dim, + const Descriptor *mask, bool back, Terminator &terminator) { using Accumulator = LocationAccumulator; Accumulator accumulator{x, target, back}; ApplyIntegerKind::template Functor, void>( @@ -293,7 +301,9 @@ static void PartialLogicalFindlocHelper(Descriptor &result, const Descriptor &x, } extern "C" { -void RTNAME(FindlocDim)(Descriptor &result, const Descriptor &x, +RT_EXT_API_GROUP_BEGIN + +void RTDEF(FindlocDim)(Descriptor &result, const Descriptor &x, const Descriptor &target, int kind, int dim, const char *source, int line, const Descriptor *mask, bool back) { Terminator terminator{source, line}; @@ -337,5 +347,7 @@ void RTNAME(FindlocDim)(Descriptor &result, const Descriptor &x, "FINDLOC: bad data type code (%d) for array", x.type().raw()); } } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/freestanding-tools.h b/flang/runtime/freestanding-tools.h index 28248f76e882af1eade555cd97900b0d8d2b54df..bdc11ae93ac9097066f09f928c439c04bbe21169 100644 --- a/flang/runtime/freestanding-tools.h +++ b/flang/runtime/freestanding-tools.h @@ -37,6 +37,11 @@ #define STD_MEMCMP_UNSUPPORTED 1 #endif +#if !defined(STD_REALLOC_UNSUPPORTED) && \ + (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__) +#define STD_REALLOC_UNSUPPORTED 1 +#endif + namespace Fortran::runtime { #if STD_FILL_N_UNSUPPORTED @@ -118,5 +123,16 @@ static inline RT_API_ATTRS int memcmp( using std::memcmp; #endif // !STD_MEMCMP_UNSUPPORTED +#if STD_REALLOC_UNSUPPORTED +static inline RT_API_ATTRS void *realloc(void *ptr, std::size_t newByteSize) { + // Return nullptr and let the callers assert that. + // TODO: we can provide a straightforward implementation + // via malloc/memcpy/free. + return nullptr; +} +#else // !STD_REALLOC_UNSUPPORTED +using std::realloc; +#endif // !STD_REALLOC_UNSUPPORTED + } // namespace Fortran::runtime #endif // FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_ diff --git a/flang/runtime/inquiry.cpp b/flang/runtime/inquiry.cpp index 5dc692c9a384a7be917bf1466e3a0e680cfa616c..2b59a1cfab1a9b0dc87690c73e4865251899c2d4 100644 --- a/flang/runtime/inquiry.cpp +++ b/flang/runtime/inquiry.cpp @@ -19,7 +19,7 @@ namespace Fortran::runtime { extern "C" { -std::int64_t RTNAME(LboundDim)( +std::int64_t RTDEF(LboundDim)( const Descriptor &array, int dim, const char *sourceFile, int line) { if (dim < 1 || dim > array.rank()) { Terminator terminator{sourceFile, line}; @@ -30,7 +30,7 @@ std::int64_t RTNAME(LboundDim)( return static_cast(dimension.LowerBound()); } -void RTNAME(Ubound)(Descriptor &result, const Descriptor &array, int kind, +void RTDEF(Ubound)(Descriptor &result, const Descriptor &array, int kind, const char *sourceFile, int line) { SubscriptValue extent[1]{array.rank()}; result.Establish(TypeCategory::Integer, kind, nullptr, 1, extent, @@ -55,7 +55,7 @@ void RTNAME(Ubound)(Descriptor &result, const Descriptor &array, int kind, } } -std::int64_t RTNAME(Size)( +std::int64_t RTDEF(Size)( const Descriptor &array, const char *sourceFile, int line) { std::int64_t result{1}; for (int i = 0; i < array.rank(); ++i) { @@ -65,7 +65,7 @@ std::int64_t RTNAME(Size)( return result; } -std::int64_t RTNAME(SizeDim)( +std::int64_t RTDEF(SizeDim)( const Descriptor &array, int dim, const char *sourceFile, int line) { if (dim < 1 || dim > array.rank()) { Terminator terminator{sourceFile, line}; diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp index 9a69a262464123cc57e2234fb6fb167f8505f931..79d43c7cc884fc120f26ae2a59057db9c671547f 100644 --- a/flang/runtime/io-api.cpp +++ b/flang/runtime/io-api.cpp @@ -185,9 +185,6 @@ template class STATE, typename... A> Cookie BeginExternalListIO( int unitNumber, const char *sourceFile, int sourceLine, A &&...xs) { Terminator terminator{sourceFile, sourceLine}; - if (unitNumber == DefaultUnit) { - unitNumber = DIR == Direction::Input ? 5 : 6; - } Cookie errorCookie{nullptr}; ExternalFileUnit *unit{GetOrCreateUnit( unitNumber, DIR, false /*!unformatted*/, terminator, errorCookie)}; @@ -246,9 +243,6 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength, const Descriptor *formatDescriptor, ExternalUnit unitNumber, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; - if (unitNumber == DefaultUnit) { - unitNumber = DIR == Direction::Input ? 5 : 6; - } Cookie errorCookie{nullptr}; ExternalFileUnit *unit{GetOrCreateUnit( unitNumber, DIR, false /*!unformatted*/, terminator, errorCookie)}; @@ -761,7 +755,8 @@ bool IONAME(SetAccess)(Cookie cookie, const char *keyword, std::size_t length) { IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetAccess() called when not in an OPEN statement"); } @@ -796,7 +791,8 @@ bool IONAME(SetAction)(Cookie cookie, const char *keyword, std::size_t length) { IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetAction() called when not in an OPEN statement"); } @@ -852,7 +848,8 @@ bool IONAME(SetAsynchronous)( handler.SignalError(IostatBadAsynchronous); } } - } else if (!io.get_if()) { + } else if (!io.get_if() && + !io.get_if()) { handler.Crash("SetAsynchronous() called when not in an OPEN or external " "I/O statement"); } @@ -864,7 +861,8 @@ bool IONAME(SetCarriagecontrol)( IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetCarriageControl() called when not in an OPEN statement"); } @@ -895,7 +893,8 @@ bool IONAME(SetConvert)( IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetConvert() called when not in an OPEN statement"); } @@ -919,7 +918,8 @@ bool IONAME(SetEncoding)( IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetEncoding() called when not in an OPEN statement"); } @@ -949,7 +949,8 @@ bool IONAME(SetForm)(Cookie cookie, const char *keyword, std::size_t length) { IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetForm() called when not in an OPEN statement"); } @@ -977,7 +978,8 @@ bool IONAME(SetPosition)( IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetPosition() called when not in an OPEN statement"); } @@ -1008,7 +1010,8 @@ bool IONAME(SetRecl)(Cookie cookie, std::size_t n) { IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetRecl() called when not in an OPEN statement"); } @@ -1093,7 +1096,8 @@ bool IONAME(SetFile)(Cookie cookie, const char *path, std::size_t chars) { } open->set_path(path, chars); return true; - } else if (!io.get_if()) { + } else if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "SetFile() called when not in an OPEN statement"); } @@ -1104,7 +1108,8 @@ bool IONAME(GetNewUnit)(Cookie cookie, int &unit, int kind) { IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - if (!io.get_if()) { + if (!io.get_if() && + !io.get_if()) { io.GetIoErrorHandler().Crash( "GetNewUnit() called when not in an OPEN statement"); } @@ -1361,7 +1366,8 @@ std::size_t IONAME(GetSize)(Cookie cookie) { if (const auto *formatted{ io.get_if>()}) { return formatted->GetEditDescriptorChars(); - } else if (!io.get_if()) { + } else if (!io.get_if() && + !io.get_if()) { handler.Crash("GetIoSize() called for an I/O statement that is not a " "formatted READ()"); } @@ -1376,7 +1382,8 @@ std::size_t IONAME(GetIoLength)(Cookie cookie) { } if (const auto *inq{io.get_if()}) { return inq->bytes(); - } else if (!io.get_if()) { + } else if (!io.get_if() && + !io.get_if()) { handler.Crash("GetIoLength() called for an I/O statement that is not " "INQUIRE(IOLENGTH=)"); } diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp index dedf1f8364ad373b6a3a87d8ab1ce122e799c720..7052a6acf41ce0a2baa113feabd86b80cc84e1c6 100644 --- a/flang/runtime/io-stmt.cpp +++ b/flang/runtime/io-stmt.cpp @@ -189,6 +189,17 @@ InternalListIoStatementState::InternalListIoStatementState( : InternalIoStatementState{d, sourceFile, sourceLine}, ioStatementState_{*this} {} +template +int InternalListIoStatementState::EndIoStatement() { + if constexpr (DIR == Direction::Input) { + if (int status{ListDirectedStatementState::EndIoStatement()}; + status != IostatOk) { + return status; + } + } + return InternalIoStatementState::EndIoStatement(); +} + ExternalIoStatementBase::ExternalIoStatementBase( ExternalFileUnit &unit, const char *sourceFile, int sourceLine) : IoStatementBase{sourceFile, sourceLine}, unit_{unit} {} @@ -569,6 +580,12 @@ std::optional IoStatementState::NextInField( case '*': case '\n': // for stream access return std::nullopt; + case '&': + case '$': + if (edit.IsNamelist()) { + return std::nullopt; + } + break; case ',': if (!(edit.modes.editingFlags & decimalComma)) { return std::nullopt; @@ -707,6 +724,13 @@ ListDirectedStatementState::GetNextDataEdit( return edit; } +int ListDirectedStatementState::EndIoStatement() { + if (repeatPosition_) { + repeatPosition_->Cancel(); + } + return IostatOk; +} + std::optional ListDirectedStatementState::GetNextDataEdit( IoStatementState &io, int maxRepeat) { @@ -818,6 +842,17 @@ ListDirectedStatementState::GetNextDataEdit( return edit; } +template +int ExternalListIoStatementState::EndIoStatement() { + if constexpr (DIR == Direction::Input) { + if (auto status{ListDirectedStatementState::EndIoStatement()}; + status != IostatOk) { + return status; + } + } + return ExternalIoStatementState::EndIoStatement(); +} + template bool ExternalUnformattedIoStatementState::Receive( char *data, std::size_t bytes, std::size_t elementBytes) { @@ -910,6 +945,16 @@ bool ChildUnformattedIoStatementState::Receive( return this->child().parent().Receive(data, bytes, elementBytes); } +template int ChildListIoStatementState::EndIoStatement() { + if constexpr (DIR == Direction::Input) { + if (int status{ListDirectedStatementState::EndIoStatement()}; + status != IostatOk) { + return status; + } + } + return ChildIoStatementState::EndIoStatement(); +} + template class InternalIoStatementState; template class InternalIoStatementState; template class InternalFormattedIoStatementState; @@ -1219,6 +1264,7 @@ bool InquireUnitState::Inquire( case HashInquiryKeyword("SIZE"): result = -1; if (unit().IsConnected()) { + unit().FlushOutput(*this); if (auto size{unit().knownSize()}) { result = *size; } @@ -1346,7 +1392,7 @@ bool InquireUnconnectedFileState::Inquire( case HashInquiryKeyword("SEQUENTIAL"): case HashInquiryKeyword("STREAM"): case HashInquiryKeyword("UNFORMATTED"): - str = "UNKNONN"; + str = "UNKNOWN"; break; case HashInquiryKeyword("READ"): str = diff --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h index 91169f6c6e323e919ff51ae6c35f523d2282de9c..0b6bcbd9af025ae6af2768a128d31a8770de6837 100644 --- a/flang/runtime/io-stmt.h +++ b/flang/runtime/io-stmt.h @@ -304,6 +304,7 @@ class ListDirectedStatementState : public FormattedIoStatementState { public: bool inNamelistSequence() const { return inNamelistSequence_; } + int EndIoStatement(); // Skips value separators, handles repetition and null values. // Vacant when '/' appears; present with descriptor == ListDirectedNullValue @@ -317,6 +318,9 @@ public: // NAMELIST input item. void ResetForNextNamelistItem(bool inNamelistSequence) { remaining_ = 0; + if (repeatPosition_) { + repeatPosition_->Cancel(); + } eatComma_ = false; realPart_ = imaginaryPart_ = false; inNamelistSequence_ = inNamelistSequence; @@ -399,6 +403,7 @@ public: const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0); IoStatementState &ioStatementState() { return ioStatementState_; } using ListDirectedStatementState::GetNextDataEdit; + int EndIoStatement(); private: IoStatementState ioStatementState_; // points to *this @@ -474,6 +479,7 @@ class ExternalListIoStatementState : public ExternalIoStatementState, public: using ExternalIoStatementState::ExternalIoStatementState; using ListDirectedStatementState::GetNextDataEdit; + int EndIoStatement(); }; template @@ -532,6 +538,7 @@ class ChildListIoStatementState : public ChildIoStatementState, public: using ChildIoStatementState::ChildIoStatementState; using ListDirectedStatementState::GetNextDataEdit; + int EndIoStatement(); }; template diff --git a/flang/runtime/matmul-transpose.cpp b/flang/runtime/matmul-transpose.cpp index 43fcf7c0849069068a327bd7758e003ec590c1d1..ee5fcd842b025808e2ed3fc87f60d743c4397c9a 100644 --- a/flang/runtime/matmul-transpose.cpp +++ b/flang/runtime/matmul-transpose.cpp @@ -31,6 +31,11 @@ namespace { using namespace Fortran::runtime; +// Suppress the warnings about calling __host__-only std::complex operators, +// defined in C++ STD header files, from __device__ code. +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // Contiguous numeric TRANSPOSE(matrix)*matrix multiplication // TRANSPOSE(matrix(n, rows)) * matrix(n,cols) -> // matrix(rows, n) * matrix(n,cols) -> matrix(rows,cols) @@ -54,7 +59,7 @@ using namespace Fortran::runtime; // 2 RES(I,J) = RES(I,J) + X(K,I)*Y(K,J) ! loop-invariant last term template -inline static void MatrixTransposedTimesMatrix( +inline static RT_API_ATTRS void MatrixTransposedTimesMatrix( CppTypeFor *RESTRICT product, SubscriptValue rows, SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y, SubscriptValue n, std::size_t xColumnByteStride = 0, @@ -85,8 +90,10 @@ inline static void MatrixTransposedTimesMatrix( } } +RT_DIAG_POP + template -inline static void MatrixTransposedTimesMatrixHelper( +inline static RT_API_ATTRS void MatrixTransposedTimesMatrixHelper( CppTypeFor *RESTRICT product, SubscriptValue rows, SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y, SubscriptValue n, std::optional xColumnByteStride, @@ -110,6 +117,9 @@ inline static void MatrixTransposedTimesMatrixHelper( } } +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // Contiguous numeric matrix*vector multiplication // matrix(rows,n) * column vector(n) -> column vector(rows) // Straightforward algorithm: @@ -126,7 +136,7 @@ inline static void MatrixTransposedTimesMatrixHelper( // 2 RES(I) = RES(I) + X(K,I)*Y(K) template -inline static void MatrixTransposedTimesVector( +inline static RT_API_ATTRS void MatrixTransposedTimesVector( CppTypeFor *RESTRICT product, SubscriptValue rows, SubscriptValue n, const XT *RESTRICT x, const YT *RESTRICT y, std::size_t xColumnByteStride = 0) { @@ -147,8 +157,10 @@ inline static void MatrixTransposedTimesVector( } } +RT_DIAG_POP + template -inline static void MatrixTransposedTimesVectorHelper( +inline static RT_API_ATTRS void MatrixTransposedTimesVectorHelper( CppTypeFor *RESTRICT product, SubscriptValue rows, SubscriptValue n, const XT *RESTRICT x, const YT *RESTRICT y, std::optional xColumnByteStride) { @@ -161,10 +173,13 @@ inline static void MatrixTransposedTimesVectorHelper( } } +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // Implements an instance of MATMUL for given argument types. template -inline static void DoMatmulTranspose( +inline static RT_API_ATTRS void DoMatmulTranspose( std::conditional_t &result, const Descriptor &x, const Descriptor &y, Terminator &terminator) { int xRank{x.rank()}; @@ -325,6 +340,8 @@ inline static void DoMatmulTranspose( } } +RT_DIAG_POP + // Maps the dynamic type information from the arguments' descriptors // to the right instantiation of DoMatmul() for valid combinations of // types. @@ -333,8 +350,9 @@ template struct MatmulTranspose { std::conditional_t; template struct MM1 { template struct MM2 { - void operator()(ResultDescriptor &result, const Descriptor &x, - const Descriptor &y, Terminator &terminator) const { + RT_API_ATTRS void operator()(ResultDescriptor &result, + const Descriptor &x, const Descriptor &y, + Terminator &terminator) const { if constexpr (constexpr auto resultType{ GetResultType(XCAT, XKIND, YCAT, YKIND)}) { if constexpr (Fortran::common::IsNumericTypeCategory( @@ -349,13 +367,13 @@ template struct MatmulTranspose { static_cast(XCAT), XKIND, static_cast(YCAT), YKIND); } }; - void operator()(ResultDescriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(ResultDescriptor &result, const Descriptor &x, const Descriptor &y, Terminator &terminator, TypeCategory yCat, int yKind) const { ApplyType(yCat, yKind, terminator, result, x, y, terminator); } }; - void operator()(ResultDescriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(ResultDescriptor &result, const Descriptor &x, const Descriptor &y, const char *sourceFile, int line) const { Terminator terminator{sourceFile, line}; auto xCatKind{x.type().GetCategoryAndKind()}; @@ -369,14 +387,17 @@ template struct MatmulTranspose { namespace Fortran::runtime { extern "C" { -void RTNAME(MatmulTranspose)(Descriptor &result, const Descriptor &x, +RT_EXT_API_GROUP_BEGIN + +void RTDEF(MatmulTranspose)(Descriptor &result, const Descriptor &x, const Descriptor &y, const char *sourceFile, int line) { MatmulTranspose{}(result, x, y, sourceFile, line); } -void RTNAME(MatmulTransposeDirect)(const Descriptor &result, - const Descriptor &x, const Descriptor &y, const char *sourceFile, - int line) { +void RTDEF(MatmulTransposeDirect)(const Descriptor &result, const Descriptor &x, + const Descriptor &y, const char *sourceFile, int line) { MatmulTranspose{}(result, x, y, sourceFile, line); } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/matmul.cpp b/flang/runtime/matmul.cpp index b46a94de01cedaf7c99a84eaede7660c449e6f64..e4595db779260f8dc61232f1daa717502c55683d 100644 --- a/flang/runtime/matmul.cpp +++ b/flang/runtime/matmul.cpp @@ -29,14 +29,21 @@ namespace Fortran::runtime { +// Suppress the warnings about calling __host__-only std::complex operators, +// defined in C++ STD header files, from __device__ code. +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // General accumulator for any type and stride; this is not used for // contiguous numeric cases. template class Accumulator { public: using Result = AccumulationType; - Accumulator(const Descriptor &x, const Descriptor &y) : x_{x}, y_{y} {} - void Accumulate(const SubscriptValue xAt[], const SubscriptValue yAt[]) { + RT_API_ATTRS Accumulator(const Descriptor &x, const Descriptor &y) + : x_{x}, y_{y} {} + RT_API_ATTRS void Accumulate( + const SubscriptValue xAt[], const SubscriptValue yAt[]) { if constexpr (RCAT == TypeCategory::Logical) { sum_ = sum_ || (IsLogicalElementTrue(x_, xAt) && IsLogicalElementTrue(y_, yAt)); @@ -45,7 +52,7 @@ public: static_cast(*y_.Element(yAt)); } } - Result GetResult() const { return sum_; } + RT_API_ATTRS Result GetResult() const { return sum_; } private: const Descriptor &x_, &y_; @@ -71,9 +78,10 @@ private: // 2 RES(I,J) = RES(I,J) + X(I,K)*Y(K,J) ! loop-invariant last term template -inline void MatrixTimesMatrix(CppTypeFor *RESTRICT product, - SubscriptValue rows, SubscriptValue cols, const XT *RESTRICT x, - const YT *RESTRICT y, SubscriptValue n, std::size_t xColumnByteStride = 0, +inline RT_API_ATTRS void MatrixTimesMatrix( + CppTypeFor *RESTRICT product, SubscriptValue rows, + SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y, + SubscriptValue n, std::size_t xColumnByteStride = 0, std::size_t yColumnByteStride = 0) { using ResultType = CppTypeFor; std::memset(product, 0, rows * cols * sizeof *product); @@ -102,11 +110,13 @@ inline void MatrixTimesMatrix(CppTypeFor *RESTRICT product, } } +RT_DIAG_POP + template -inline void MatrixTimesMatrixHelper(CppTypeFor *RESTRICT product, - SubscriptValue rows, SubscriptValue cols, const XT *RESTRICT x, - const YT *RESTRICT y, SubscriptValue n, - std::optional xColumnByteStride, +inline RT_API_ATTRS void MatrixTimesMatrixHelper( + CppTypeFor *RESTRICT product, SubscriptValue rows, + SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y, + SubscriptValue n, std::optional xColumnByteStride, std::optional yColumnByteStride) { if (!xColumnByteStride) { if (!yColumnByteStride) { @@ -127,6 +137,9 @@ inline void MatrixTimesMatrixHelper(CppTypeFor *RESTRICT product, } } +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // Contiguous numeric matrix*vector multiplication // matrix(rows,n) * column vector(n) -> column vector(rows) // Straightforward algorithm: @@ -143,9 +156,10 @@ inline void MatrixTimesMatrixHelper(CppTypeFor *RESTRICT product, // 2 RES(J) = RES(J) + X(J,K)*Y(K) template -inline void MatrixTimesVector(CppTypeFor *RESTRICT product, - SubscriptValue rows, SubscriptValue n, const XT *RESTRICT x, - const YT *RESTRICT y, std::size_t xColumnByteStride = 0) { +inline RT_API_ATTRS void MatrixTimesVector( + CppTypeFor *RESTRICT product, SubscriptValue rows, + SubscriptValue n, const XT *RESTRICT x, const YT *RESTRICT y, + std::size_t xColumnByteStride = 0) { using ResultType = CppTypeFor; std::memset(product, 0, rows * sizeof *product); [[maybe_unused]] const XT *RESTRICT xp0{x}; @@ -163,10 +177,13 @@ inline void MatrixTimesVector(CppTypeFor *RESTRICT product, } } +RT_DIAG_POP + template -inline void MatrixTimesVectorHelper(CppTypeFor *RESTRICT product, - SubscriptValue rows, SubscriptValue n, const XT *RESTRICT x, - const YT *RESTRICT y, std::optional xColumnByteStride) { +inline RT_API_ATTRS void MatrixTimesVectorHelper( + CppTypeFor *RESTRICT product, SubscriptValue rows, + SubscriptValue n, const XT *RESTRICT x, const YT *RESTRICT y, + std::optional xColumnByteStride) { if (!xColumnByteStride) { MatrixTimesVector(product, rows, n, x, y); } else { @@ -175,6 +192,9 @@ inline void MatrixTimesVectorHelper(CppTypeFor *RESTRICT product, } } +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // Contiguous numeric vector*matrix multiplication // row vector(n) * matrix(n,cols) -> row vector(cols) // Straightforward algorithm: @@ -191,9 +211,10 @@ inline void MatrixTimesVectorHelper(CppTypeFor *RESTRICT product, // 2 RES(J) = RES(J) + X(K)*Y(K,J) template -inline void VectorTimesMatrix(CppTypeFor *RESTRICT product, - SubscriptValue n, SubscriptValue cols, const XT *RESTRICT x, - const YT *RESTRICT y, std::size_t yColumnByteStride = 0) { +inline RT_API_ATTRS void VectorTimesMatrix( + CppTypeFor *RESTRICT product, SubscriptValue n, + SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y, + std::size_t yColumnByteStride = 0) { using ResultType = CppTypeFor; std::memset(product, 0, cols * sizeof *product); for (SubscriptValue k{0}; k < n; ++k) { @@ -212,11 +233,14 @@ inline void VectorTimesMatrix(CppTypeFor *RESTRICT product, } } +RT_DIAG_POP + template -inline void VectorTimesMatrixHelper(CppTypeFor *RESTRICT product, - SubscriptValue n, SubscriptValue cols, const XT *RESTRICT x, - const YT *RESTRICT y, std::optional yColumnByteStride) { +inline RT_API_ATTRS void VectorTimesMatrixHelper( + CppTypeFor *RESTRICT product, SubscriptValue n, + SubscriptValue cols, const XT *RESTRICT x, const YT *RESTRICT y, + std::optional yColumnByteStride) { if (!yColumnByteStride) { VectorTimesMatrix(product, n, cols, x, y); } else { @@ -225,10 +249,13 @@ inline void VectorTimesMatrixHelper(CppTypeFor *RESTRICT product, } } +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // Implements an instance of MATMUL for given argument types. template -static inline void DoMatmul( +static inline RT_API_ATTRS void DoMatmul( std::conditional_t &result, const Descriptor &x, const Descriptor &y, Terminator &terminator) { int xRank{x.rank()}; @@ -398,6 +425,8 @@ static inline void DoMatmul( } } +RT_DIAG_POP + // Maps the dynamic type information from the arguments' descriptors // to the right instantiation of DoMatmul() for valid combinations of // types. @@ -406,8 +435,9 @@ template struct Matmul { std::conditional_t; template struct MM1 { template struct MM2 { - void operator()(ResultDescriptor &result, const Descriptor &x, - const Descriptor &y, Terminator &terminator) const { + RT_API_ATTRS void operator()(ResultDescriptor &result, + const Descriptor &x, const Descriptor &y, + Terminator &terminator) const { if constexpr (constexpr auto resultType{ GetResultType(XCAT, XKIND, YCAT, YKIND)}) { if constexpr (common::IsNumericTypeCategory(resultType->first) || @@ -421,13 +451,13 @@ template struct Matmul { static_cast(XCAT), XKIND, static_cast(YCAT), YKIND); } }; - void operator()(ResultDescriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(ResultDescriptor &result, const Descriptor &x, const Descriptor &y, Terminator &terminator, TypeCategory yCat, int yKind) const { ApplyType(yCat, yKind, terminator, result, x, y, terminator); } }; - void operator()(ResultDescriptor &result, const Descriptor &x, + RT_API_ATTRS void operator()(ResultDescriptor &result, const Descriptor &x, const Descriptor &y, const char *sourceFile, int line) const { Terminator terminator{sourceFile, line}; auto xCatKind{x.type().GetCategoryAndKind()}; @@ -439,13 +469,17 @@ template struct Matmul { }; extern "C" { -void RTNAME(Matmul)(Descriptor &result, const Descriptor &x, - const Descriptor &y, const char *sourceFile, int line) { +RT_EXT_API_GROUP_BEGIN + +void RTDEF(Matmul)(Descriptor &result, const Descriptor &x, const Descriptor &y, + const char *sourceFile, int line) { Matmul{}(result, x, y, sourceFile, line); } -void RTNAME(MatmulDirect)(const Descriptor &result, const Descriptor &x, +void RTDEF(MatmulDirect)(const Descriptor &result, const Descriptor &x, const Descriptor &y, const char *sourceFile, int line) { Matmul{}(result, x, y, sourceFile, line); } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/memory.cpp b/flang/runtime/memory.cpp index 5ed737905a9cb0be93efa3b7a4be36e933e63eff..aa6ff9723d1a80696ca21d1400338ecd95c02bbd 100644 --- a/flang/runtime/memory.cpp +++ b/flang/runtime/memory.cpp @@ -8,11 +8,14 @@ #include "flang/Runtime/memory.h" #include "terminator.h" +#include "tools.h" #include namespace Fortran::runtime { +RT_OFFLOAD_VAR_GROUP_BEGIN -void *AllocateMemoryOrCrash(const Terminator &terminator, std::size_t bytes) { +RT_API_ATTRS void *AllocateMemoryOrCrash( + const Terminator &terminator, std::size_t bytes) { if (void *p{std::malloc(bytes)}) { return p; } @@ -24,5 +27,20 @@ void *AllocateMemoryOrCrash(const Terminator &terminator, std::size_t bytes) { return nullptr; } -void FreeMemory(void *p) { std::free(p); } +RT_API_ATTRS void *ReallocateMemoryOrCrash( + const Terminator &terminator, void *ptr, std::size_t newByteSize) { + if (void *p{Fortran::runtime::realloc(ptr, newByteSize)}) { + return p; + } + if (newByteSize > 0) { + terminator.Crash("Fortran runtime internal error: memory realloc returned " + "null, needed %zd bytes", + newByteSize); + } + return nullptr; +} + +RT_API_ATTRS void FreeMemory(void *p) { std::free(p); } + +RT_OFFLOAD_VAR_GROUP_END } // namespace Fortran::runtime diff --git a/flang/runtime/misc-intrinsic.cpp b/flang/runtime/misc-intrinsic.cpp index 19eb9351d47fc7550a4202925a0ee830573bb74c..56f2028c2ff02cad28a36e8350816831c78fcc29 100644 --- a/flang/runtime/misc-intrinsic.cpp +++ b/flang/runtime/misc-intrinsic.cpp @@ -8,6 +8,7 @@ #include "flang/Runtime/misc-intrinsic.h" #include "terminator.h" +#include "tools.h" #include "flang/Runtime/descriptor.h" #include #include @@ -15,9 +16,9 @@ namespace Fortran::runtime { -static void TransferImpl(Descriptor &result, const Descriptor &source, - const Descriptor &mold, const char *sourceFile, int line, - std::optional resultExtent) { +static RT_API_ATTRS void TransferImpl(Descriptor &result, + const Descriptor &source, const Descriptor &mold, const char *sourceFile, + int line, std::optional resultExtent) { int rank{resultExtent.has_value() ? 1 : 0}; std::size_t elementBytes{mold.ElementBytes()}; result.Establish(mold.type(), elementBytes, nullptr, rank, nullptr, @@ -52,8 +53,9 @@ static void TransferImpl(Descriptor &result, const Descriptor &source, } extern "C" { +RT_EXT_API_GROUP_BEGIN -void RTNAME(Transfer)(Descriptor &result, const Descriptor &source, +void RTDEF(Transfer)(Descriptor &result, const Descriptor &source, const Descriptor &mold, const char *sourceFile, int line) { std::optional elements; if (mold.rank() > 0) { @@ -67,18 +69,19 @@ void RTNAME(Transfer)(Descriptor &result, const Descriptor &source, "when SOURCE= is not zero-sized"); } } else { - elements = 0; + elements = std::int64_t{0}; } } return TransferImpl( result, source, mold, sourceFile, line, std::move(elements)); } -void RTNAME(TransferSize)(Descriptor &result, const Descriptor &source, +void RTDEF(TransferSize)(Descriptor &result, const Descriptor &source, const Descriptor &mold, const char *sourceFile, int line, std::int64_t size) { return TransferImpl(result, source, mold, sourceFile, line, size); } +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/namelist.cpp b/flang/runtime/namelist.cpp index 61815a7cc8a40328f91bd77f64e7d5725ee0fb15..e6997bcf945b80c5dd3f45995d248f66f077d18b 100644 --- a/flang/runtime/namelist.cpp +++ b/flang/runtime/namelist.cpp @@ -82,7 +82,7 @@ bool IONAME(OutputNamelist)(Cookie cookie, const NamelistGroup &group) { static constexpr bool IsLegalIdStart(char32_t ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_' || - ch == '@' || ch == '$'; + ch == '@'; } static constexpr bool IsLegalIdChar(char32_t ch) { @@ -247,6 +247,28 @@ static bool HandleSubscripts(IoStatementState &io, Descriptor &desc, return false; } +static void StorageSequenceExtension( + Descriptor &desc, const Descriptor &source) { + // Support the near-universal extension of NAMELIST input into a + // designatable storage sequence identified by its initial scalar array + // element. For example, treat "A(1) = 1. 2. 3." as if it had been + // "A(1:) = 1. 2. 3.". + if (desc.rank() == 0 && (source.rank() == 1 || source.IsContiguous())) { + if (auto stride{source.rank() == 1 + ? source.GetDimension(0).ByteStride() + : static_cast(source.ElementBytes())}; + stride != 0) { + desc.raw().attribute = CFI_attribute_pointer; + desc.raw().rank = 1; + desc.GetDimension(0) + .SetBounds(1, + source.Elements() - + ((source.OffsetElement() - desc.OffsetElement()) / stride)) + .SetByteStride(stride); + } + } +} + static bool HandleSubstring( IoStatementState &io, Descriptor &desc, const char *name) { IoErrorHandler &handler{io.GetIoErrorHandler()}; @@ -378,12 +400,13 @@ static bool HandleComponent(IoStatementState &io, Descriptor &desc, return false; } -// Advance to the terminal '/' of a namelist group. +// Advance to the terminal '/' of a namelist group or leading '&'/'$' +// of the next. static void SkipNamelistGroup(IoStatementState &io) { std::size_t byteCount{0}; while (auto ch{io.GetNextNonBlank(byteCount)}) { io.HandleRelativePosition(byteCount); - if (*ch == '/') { + if (*ch == '/' || *ch == '&' || *ch == '$') { break; } else if (*ch == '\'' || *ch == '"') { // Skip quoted character literal @@ -418,7 +441,7 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { std::size_t byteCount{0}; while (true) { next = io.GetNextNonBlank(byteCount); - while (next && *next != '&') { + while (next && *next != '&' && *next != '$') { // Extension: comment lines without ! before namelist groups if (!io.AdvanceRecord()) { next.reset(); @@ -430,9 +453,10 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { handler.SignalEnd(); return false; } - if (*next != '&') { + if (*next != '&' && *next != '$') { handler.SignalError( - "NAMELIST input group does not begin with '&' (at '%lc')", *next); + "NAMELIST input group does not begin with '&' or '$' (at '%lc')", + *next); return false; } io.HandleRelativePosition(byteCount); @@ -448,7 +472,7 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { // Read the group's items while (true) { next = io.GetNextNonBlank(byteCount); - if (!next || *next == '/') { + if (!next || *next == '/' || *next == '&' || *next == '$') { break; } if (!GetLowerCaseName(io, name, sizeof name)) { @@ -478,10 +502,14 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { bool hadSubscripts{false}; bool hadSubstring{false}; if (next && (*next == '(' || *next == '%')) { + const Descriptor *lastSubscriptBase{nullptr}; + Descriptor *lastSubscriptDescriptor{nullptr}; do { Descriptor &mutableDescriptor{staticDesc[whichStaticDesc].descriptor()}; whichStaticDesc ^= 1; io.HandleRelativePosition(byteCount); // skip over '(' or '%' + lastSubscriptDescriptor = nullptr; + lastSubscriptBase = nullptr; if (*next == '(') { if (!hadSubstring && (hadSubscripts || useDescriptor->rank() == 0)) { mutableDescriptor = *useDescriptor; @@ -495,11 +523,12 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { "NAMELIST group '%s'", name, group.groupName); return false; + } else if (HandleSubscripts( + io, mutableDescriptor, *useDescriptor, name)) { + lastSubscriptBase = useDescriptor; + lastSubscriptDescriptor = &mutableDescriptor; } else { - if (!HandleSubscripts( - io, mutableDescriptor, *useDescriptor, name)) { - return false; - } + return false; } hadSubscripts = true; } else { @@ -512,6 +541,9 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { useDescriptor = &mutableDescriptor; next = io.GetCurrentChar(byteCount); } while (next && (*next == '(' || *next == '%')); + if (lastSubscriptDescriptor) { + StorageSequenceExtension(*lastSubscriptDescriptor, *lastSubscriptBase); + } } // Skip the '=' next = io.GetNextNonBlank(byteCount); @@ -540,12 +572,15 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) { io.HandleRelativePosition(byteCount); } } - if (!next || *next != '/') { + if (next && *next == '/') { + io.HandleRelativePosition(byteCount); + } else if (*next && (*next == '&' || *next == '$')) { + // stop at beginning of next group + } else { handler.SignalError( "No '/' found after NAMELIST group '%s'", group.groupName); return false; } - io.HandleRelativePosition(byteCount); return true; } @@ -565,7 +600,7 @@ bool IsNamelistNameOrSlash(IoStatementState &io) { // TODO: how to deal with NaN(...) ambiguity? return ch && (*ch == '=' || *ch == '(' || *ch == '%'); } else { - return *ch == '/'; + return *ch == '/' || *ch == '&' || *ch == '$'; } } } diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp index cd54e6b54a2e536f37ada48f3391fc6b2df1b9f3..6cbf00e0c36c787e290d243df730141b73d83ed8 100644 --- a/flang/runtime/numeric.cpp +++ b/flang/runtime/numeric.cpp @@ -17,8 +17,8 @@ namespace Fortran::runtime { template -inline RES getIntArgValue(const char *source, int line, void *arg, int kind, - std::int64_t defaultValue, int resKind) { +inline RT_API_ATTRS RES getIntArgValue(const char *source, int line, void *arg, + int kind, std::int64_t defaultValue, int resKind) { RES res; if (!arg) { res = static_cast(defaultValue); @@ -49,7 +49,8 @@ inline RES getIntArgValue(const char *source, int line, void *arg, int kind, } // NINT (16.9.141) -template inline RESULT Nint(ARG x) { +template +inline RT_API_ATTRS RESULT Nint(ARG x) { if (x >= 0) { return std::trunc(x + ARG{0.5}); } else { @@ -58,15 +59,18 @@ template inline RESULT Nint(ARG x) { } // CEILING & FLOOR (16.9.43, .79) -template inline RESULT Ceiling(ARG x) { +template +inline RT_API_ATTRS RESULT Ceiling(ARG x) { return std::ceil(x); } -template inline RESULT Floor(ARG x) { +template +inline RT_API_ATTRS RESULT Floor(ARG x) { return std::floor(x); } // EXPONENT (16.9.75) -template inline RESULT Exponent(ARG x) { +template +inline RT_API_ATTRS RESULT Exponent(ARG x) { if (std::isinf(x) || std::isnan(x)) { return std::numeric_limits::max(); // +/-Inf, NaN -> HUGE(0) } else if (x == 0) { @@ -76,8 +80,13 @@ template inline RESULT Exponent(ARG x) { } } +// Suppress the warnings about calling __host__-only std::frexp, +// defined in C++ STD header files, from __device__ code. +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + // FRACTION (16.9.80) -template inline T Fraction(T x) { +template inline RT_API_ATTRS T Fraction(T x) { if (std::isnan(x)) { return x; // NaN -> same NaN } else if (std::isinf(x)) { @@ -90,9 +99,11 @@ template inline T Fraction(T x) { } } +RT_DIAG_POP + // MOD & MODULO (16.9.135, .136) template -inline T IntMod(T x, T p, const char *sourceFile, int sourceLine) { +inline RT_API_ATTRS T IntMod(T x, T p, const char *sourceFile, int sourceLine) { if (p == 0) { Terminator{sourceFile, sourceLine}.Crash( IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); @@ -104,7 +115,8 @@ inline T IntMod(T x, T p, const char *sourceFile, int sourceLine) { return mod; } template -inline T RealMod(T a, T p, const char *sourceFile, int sourceLine) { +inline RT_API_ATTRS T RealMod( + T a, T p, const char *sourceFile, int sourceLine) { if (p == 0) { Terminator{sourceFile, sourceLine}.Crash( IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); @@ -120,7 +132,7 @@ inline T RealMod(T a, T p, const char *sourceFile, int sourceLine) { } // RRSPACING (16.9.164) -template inline T RRSpacing(T x) { +template inline RT_API_ATTRS T RRSpacing(T x) { if (std::isnan(x)) { return x; // NaN -> same NaN } else if (std::isinf(x)) { @@ -133,7 +145,7 @@ template inline T RRSpacing(T x) { } // SCALE (16.9.166) -template inline T Scale(T x, std::int64_t p) { +template inline RT_API_ATTRS T Scale(T x, std::int64_t p) { auto ip{static_cast(p)}; if (ip != p) { ip = p < 0 ? std::numeric_limits::min() @@ -144,7 +156,7 @@ template inline T Scale(T x, std::int64_t p) { // SELECTED_INT_KIND (16.9.169) template -inline CppTypeFor SelectedIntKind(T x) { +inline RT_API_ATTRS CppTypeFor SelectedIntKind(T x) { if (x <= 2) { return 1; } else if (x <= 4) { @@ -163,7 +175,8 @@ inline CppTypeFor SelectedIntKind(T x) { // SELECTED_REAL_KIND (16.9.170) template -inline CppTypeFor SelectedRealKind(P p, R r, D d) { +inline RT_API_ATTRS CppTypeFor SelectedRealKind( + P p, R r, D d) { if (d != 2) { return -5; } @@ -210,7 +223,7 @@ inline CppTypeFor SelectedRealKind(P p, R r, D d) { } // SET_EXPONENT (16.9.171) -template inline T SetExponent(T x, std::int64_t p) { +template inline RT_API_ATTRS T SetExponent(T x, std::int64_t p) { if (std::isnan(x)) { return x; // NaN -> same NaN } else if (std::isinf(x)) { @@ -229,7 +242,7 @@ template inline T SetExponent(T x, std::int64_t p) { } // SPACING (16.9.180) -template inline T Spacing(T x) { +template inline RT_API_ATTRS T Spacing(T x) { if (std::isnan(x)) { return x; // NaN -> same NaN } else if (std::isinf(x)) { @@ -246,18 +259,18 @@ template inline T Spacing(T x) { } // NEAREST (16.9.139) -template inline T Nearest(T x, bool positive) { - auto spacing{Spacing(x)}; - if (x == 0) { - auto least{std::numeric_limits::denorm_min()}; - return positive ? least : -least; +template +inline RT_API_ATTRS T Nearest(T x, bool positive) { + if (positive) { + return std::nextafter(x, std::numeric_limits::infinity()); } else { - return positive ? x + spacing : x - spacing; + return std::nextafter(x, -std::numeric_limits::infinity()); } } // Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1). -template BTy FPowI(BTy base, ETy exp) { +template +RT_API_ATTRS BTy FPowI(BTy base, ETy exp) { if (exp == ETy{0}) return BTy{1}; bool isNegativePower{exp < ETy{0}}; @@ -289,565 +302,566 @@ template BTy FPowI(BTy base, ETy exp) { } extern "C" { +RT_EXT_API_GROUP_BEGIN -CppTypeFor RTNAME(Ceiling4_1)( +CppTypeFor RTDEF(Ceiling4_1)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling4_2)( +CppTypeFor RTDEF(Ceiling4_2)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling4_4)( +CppTypeFor RTDEF(Ceiling4_4)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling4_8)( +CppTypeFor RTDEF(Ceiling4_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Ceiling4_16)( +CppTypeFor RTDEF(Ceiling4_16)( CppTypeFor x) { return Ceiling>(x); } #endif -CppTypeFor RTNAME(Ceiling8_1)( +CppTypeFor RTDEF(Ceiling8_1)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling8_2)( +CppTypeFor RTDEF(Ceiling8_2)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling8_4)( +CppTypeFor RTDEF(Ceiling8_4)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling8_8)( +CppTypeFor RTDEF(Ceiling8_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Ceiling8_16)( +CppTypeFor RTDEF(Ceiling8_16)( CppTypeFor x) { return Ceiling>(x); } #endif #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Ceiling10_1)( +CppTypeFor RTDEF(Ceiling10_1)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling10_2)( +CppTypeFor RTDEF(Ceiling10_2)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling10_4)( +CppTypeFor RTDEF(Ceiling10_4)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling10_8)( +CppTypeFor RTDEF(Ceiling10_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Ceiling10_16)( +CppTypeFor RTDEF(Ceiling10_16)( CppTypeFor x) { return Ceiling>(x); } #endif #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Ceiling16_1)( +CppTypeFor RTDEF(Ceiling16_1)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling16_2)( +CppTypeFor RTDEF(Ceiling16_2)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling16_4)( +CppTypeFor RTDEF(Ceiling16_4)( CppTypeFor x) { return Ceiling>(x); } -CppTypeFor RTNAME(Ceiling16_8)( +CppTypeFor RTDEF(Ceiling16_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Ceiling16_16)( +CppTypeFor RTDEF(Ceiling16_16)( CppTypeFor x) { return Ceiling>(x); } #endif #endif -CppTypeFor RTNAME(Exponent4_4)( +CppTypeFor RTDEF(Exponent4_4)( CppTypeFor x) { return Exponent>(x); } -CppTypeFor RTNAME(Exponent4_8)( +CppTypeFor RTDEF(Exponent4_8)( CppTypeFor x) { return Exponent>(x); } -CppTypeFor RTNAME(Exponent8_4)( +CppTypeFor RTDEF(Exponent8_4)( CppTypeFor x) { return Exponent>(x); } -CppTypeFor RTNAME(Exponent8_8)( +CppTypeFor RTDEF(Exponent8_8)( CppTypeFor x) { return Exponent>(x); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Exponent10_4)( +CppTypeFor RTDEF(Exponent10_4)( CppTypeFor x) { return Exponent>(x); } -CppTypeFor RTNAME(Exponent10_8)( +CppTypeFor RTDEF(Exponent10_8)( CppTypeFor x) { return Exponent>(x); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Exponent16_4)( +CppTypeFor RTDEF(Exponent16_4)( CppTypeFor x) { return Exponent>(x); } -CppTypeFor RTNAME(Exponent16_8)( +CppTypeFor RTDEF(Exponent16_8)( CppTypeFor x) { return Exponent>(x); } #endif -CppTypeFor RTNAME(Floor4_1)( +CppTypeFor RTDEF(Floor4_1)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor4_2)( +CppTypeFor RTDEF(Floor4_2)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor4_4)( +CppTypeFor RTDEF(Floor4_4)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor4_8)( +CppTypeFor RTDEF(Floor4_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Floor4_16)( +CppTypeFor RTDEF(Floor4_16)( CppTypeFor x) { return Floor>(x); } #endif -CppTypeFor RTNAME(Floor8_1)( +CppTypeFor RTDEF(Floor8_1)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor8_2)( +CppTypeFor RTDEF(Floor8_2)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor8_4)( +CppTypeFor RTDEF(Floor8_4)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor8_8)( +CppTypeFor RTDEF(Floor8_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Floor8_16)( +CppTypeFor RTDEF(Floor8_16)( CppTypeFor x) { return Floor>(x); } #endif #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Floor10_1)( +CppTypeFor RTDEF(Floor10_1)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor10_2)( +CppTypeFor RTDEF(Floor10_2)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor10_4)( +CppTypeFor RTDEF(Floor10_4)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor10_8)( +CppTypeFor RTDEF(Floor10_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Floor10_16)( +CppTypeFor RTDEF(Floor10_16)( CppTypeFor x) { return Floor>(x); } #endif #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Floor16_1)( +CppTypeFor RTDEF(Floor16_1)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor16_2)( +CppTypeFor RTDEF(Floor16_2)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor16_4)( +CppTypeFor RTDEF(Floor16_4)( CppTypeFor x) { return Floor>(x); } -CppTypeFor RTNAME(Floor16_8)( +CppTypeFor RTDEF(Floor16_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Floor16_16)( +CppTypeFor RTDEF(Floor16_16)( CppTypeFor x) { return Floor>(x); } #endif #endif -CppTypeFor RTNAME(Fraction4)( +CppTypeFor RTDEF(Fraction4)( CppTypeFor x) { return Fraction(x); } -CppTypeFor RTNAME(Fraction8)( +CppTypeFor RTDEF(Fraction8)( CppTypeFor x) { return Fraction(x); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Fraction10)( +CppTypeFor RTDEF(Fraction10)( CppTypeFor x) { return Fraction(x); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Fraction16)( +CppTypeFor RTDEF(Fraction16)( CppTypeFor x) { return Fraction(x); } #endif -bool RTNAME(IsFinite4)(CppTypeFor x) { +bool RTDEF(IsFinite4)(CppTypeFor x) { return std::isfinite(x); } -bool RTNAME(IsFinite8)(CppTypeFor x) { +bool RTDEF(IsFinite8)(CppTypeFor x) { return std::isfinite(x); } #if LDBL_MANT_DIG == 64 -bool RTNAME(IsFinite10)(CppTypeFor x) { +bool RTDEF(IsFinite10)(CppTypeFor x) { return std::isfinite(x); } #elif LDBL_MANT_DIG == 113 -bool RTNAME(IsFinite16)(CppTypeFor x) { +bool RTDEF(IsFinite16)(CppTypeFor x) { return std::isfinite(x); } #endif -bool RTNAME(IsNaN4)(CppTypeFor x) { +bool RTDEF(IsNaN4)(CppTypeFor x) { return std::isnan(x); } -bool RTNAME(IsNaN8)(CppTypeFor x) { +bool RTDEF(IsNaN8)(CppTypeFor x) { return std::isnan(x); } #if LDBL_MANT_DIG == 64 -bool RTNAME(IsNaN10)(CppTypeFor x) { +bool RTDEF(IsNaN10)(CppTypeFor x) { return std::isnan(x); } #elif LDBL_MANT_DIG == 113 -bool RTNAME(IsNaN16)(CppTypeFor x) { +bool RTDEF(IsNaN16)(CppTypeFor x) { return std::isnan(x); } #endif -CppTypeFor RTNAME(ModInteger1)( +CppTypeFor RTDEF(ModInteger1)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModInteger2)( +CppTypeFor RTDEF(ModInteger2)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModInteger4)( +CppTypeFor RTDEF(ModInteger4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModInteger8)( +CppTypeFor RTDEF(ModInteger8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(ModInteger16)( +CppTypeFor RTDEF(ModInteger16)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #endif -CppTypeFor RTNAME(ModReal4)( +CppTypeFor RTDEF(ModReal4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModReal8)( +CppTypeFor RTDEF(ModReal8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(ModReal10)( +CppTypeFor RTDEF(ModReal10)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(ModReal16)( +CppTypeFor RTDEF(ModReal16)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #endif -CppTypeFor RTNAME(ModuloInteger1)( +CppTypeFor RTDEF(ModuloInteger1)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModuloInteger2)( +CppTypeFor RTDEF(ModuloInteger2)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModuloInteger4)( +CppTypeFor RTDEF(ModuloInteger4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModuloInteger8)( +CppTypeFor RTDEF(ModuloInteger8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(ModuloInteger16)( +CppTypeFor RTDEF(ModuloInteger16)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #endif -CppTypeFor RTNAME(ModuloReal4)( +CppTypeFor RTDEF(ModuloReal4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } -CppTypeFor RTNAME(ModuloReal8)( +CppTypeFor RTDEF(ModuloReal8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(ModuloReal10)( +CppTypeFor RTDEF(ModuloReal10)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(ModuloReal16)( +CppTypeFor RTDEF(ModuloReal16)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #endif -CppTypeFor RTNAME(Nearest4)( +CppTypeFor RTDEF(Nearest4)( CppTypeFor x, bool positive) { return Nearest<24>(x, positive); } -CppTypeFor RTNAME(Nearest8)( +CppTypeFor RTDEF(Nearest8)( CppTypeFor x, bool positive) { return Nearest<53>(x, positive); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Nearest10)( +CppTypeFor RTDEF(Nearest10)( CppTypeFor x, bool positive) { return Nearest<64>(x, positive); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Nearest16)( +CppTypeFor RTDEF(Nearest16)( CppTypeFor x, bool positive) { return Nearest<113>(x, positive); } #endif -CppTypeFor RTNAME(Nint4_1)( +CppTypeFor RTDEF(Nint4_1)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint4_2)( +CppTypeFor RTDEF(Nint4_2)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint4_4)( +CppTypeFor RTDEF(Nint4_4)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint4_8)( +CppTypeFor RTDEF(Nint4_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Nint4_16)( +CppTypeFor RTDEF(Nint4_16)( CppTypeFor x) { return Nint>(x); } #endif -CppTypeFor RTNAME(Nint8_1)( +CppTypeFor RTDEF(Nint8_1)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint8_2)( +CppTypeFor RTDEF(Nint8_2)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint8_4)( +CppTypeFor RTDEF(Nint8_4)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint8_8)( +CppTypeFor RTDEF(Nint8_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Nint8_16)( +CppTypeFor RTDEF(Nint8_16)( CppTypeFor x) { return Nint>(x); } #endif #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Nint10_1)( +CppTypeFor RTDEF(Nint10_1)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint10_2)( +CppTypeFor RTDEF(Nint10_2)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint10_4)( +CppTypeFor RTDEF(Nint10_4)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint10_8)( +CppTypeFor RTDEF(Nint10_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Nint10_16)( +CppTypeFor RTDEF(Nint10_16)( CppTypeFor x) { return Nint>(x); } #endif #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Nint16_1)( +CppTypeFor RTDEF(Nint16_1)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint16_2)( +CppTypeFor RTDEF(Nint16_2)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint16_4)( +CppTypeFor RTDEF(Nint16_4)( CppTypeFor x) { return Nint>(x); } -CppTypeFor RTNAME(Nint16_8)( +CppTypeFor RTDEF(Nint16_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T -CppTypeFor RTNAME(Nint16_16)( +CppTypeFor RTDEF(Nint16_16)( CppTypeFor x) { return Nint>(x); } #endif #endif -CppTypeFor RTNAME(RRSpacing4)( +CppTypeFor RTDEF(RRSpacing4)( CppTypeFor x) { return RRSpacing<24>(x); } -CppTypeFor RTNAME(RRSpacing8)( +CppTypeFor RTDEF(RRSpacing8)( CppTypeFor x) { return RRSpacing<53>(x); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(RRSpacing10)( +CppTypeFor RTDEF(RRSpacing10)( CppTypeFor x) { return RRSpacing<64>(x); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(RRSpacing16)( +CppTypeFor RTDEF(RRSpacing16)( CppTypeFor x) { return RRSpacing<113>(x); } #endif -CppTypeFor RTNAME(SetExponent4)( +CppTypeFor RTDEF(SetExponent4)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } -CppTypeFor RTNAME(SetExponent8)( +CppTypeFor RTDEF(SetExponent8)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(SetExponent10)( +CppTypeFor RTDEF(SetExponent10)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(SetExponent16)( +CppTypeFor RTDEF(SetExponent16)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } #endif -CppTypeFor RTNAME(Scale4)( +CppTypeFor RTDEF(Scale4)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } -CppTypeFor RTNAME(Scale8)( +CppTypeFor RTDEF(Scale8)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Scale10)( +CppTypeFor RTDEF(Scale10)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Scale16)( +CppTypeFor RTDEF(Scale16)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } #endif // SELECTED_INT_KIND -CppTypeFor RTNAME(SelectedIntKind)( +CppTypeFor RTDEF(SelectedIntKind)( const char *source, int line, void *x, int xKind) { #ifdef __SIZEOF_INT128__ CppTypeFor r = @@ -861,9 +875,9 @@ CppTypeFor RTNAME(SelectedIntKind)( } // SELECTED_REAL_KIND -CppTypeFor RTNAME(SelectedRealKind)( - const char *source, int line, void *precision, int pKind, void *range, - int rKind, void *radix, int dKind) { +CppTypeFor RTDEF(SelectedRealKind)(const char *source, + int line, void *precision, int pKind, void *range, int rKind, void *radix, + int dKind) { #ifdef __SIZEOF_INT128__ CppTypeFor p = getIntArgValue>( @@ -885,74 +899,76 @@ CppTypeFor RTNAME(SelectedRealKind)( return SelectedRealKind(p, r, d); } -CppTypeFor RTNAME(Spacing4)( +CppTypeFor RTDEF(Spacing4)( CppTypeFor x) { return Spacing<24>(x); } -CppTypeFor RTNAME(Spacing8)( +CppTypeFor RTDEF(Spacing8)( CppTypeFor x) { return Spacing<53>(x); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(Spacing10)( +CppTypeFor RTDEF(Spacing10)( CppTypeFor x) { return Spacing<64>(x); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(Spacing16)( +CppTypeFor RTDEF(Spacing16)( CppTypeFor x) { return Spacing<113>(x); } #endif -CppTypeFor RTNAME(FPow4i)( +CppTypeFor RTDEF(FPow4i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } -CppTypeFor RTNAME(FPow8i)( +CppTypeFor RTDEF(FPow8i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(FPow10i)( +CppTypeFor RTDEF(FPow10i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(FPow16i)( +CppTypeFor RTDEF(FPow16i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif -CppTypeFor RTNAME(FPow4k)( +CppTypeFor RTDEF(FPow4k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } -CppTypeFor RTNAME(FPow8k)( +CppTypeFor RTDEF(FPow8k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(FPow10k)( +CppTypeFor RTDEF(FPow10k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif #if LDBL_MANT_DIG == 113 || HAS_FLOAT128 -CppTypeFor RTNAME(FPow16k)( +CppTypeFor RTDEF(FPow16k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/pointer.cpp b/flang/runtime/pointer.cpp index b0003add7b3585187916bffa00b646c8d88a6638..f83c00089813eb0a5c7a2edc88e2d6e2084b40be 100644 --- a/flang/runtime/pointer.cpp +++ b/flang/runtime/pointer.cpp @@ -16,8 +16,9 @@ namespace Fortran::runtime { extern "C" { +RT_EXT_API_GROUP_BEGIN -void RTNAME(PointerNullifyIntrinsic)(Descriptor &pointer, TypeCategory category, +void RTDEF(PointerNullifyIntrinsic)(Descriptor &pointer, TypeCategory category, int kind, int rank, int corank) { INTERNAL_CHECK(corank == 0); pointer.Establish(TypeCode{category, kind}, @@ -25,20 +26,20 @@ void RTNAME(PointerNullifyIntrinsic)(Descriptor &pointer, TypeCategory category, CFI_attribute_pointer); } -void RTNAME(PointerNullifyCharacter)(Descriptor &pointer, SubscriptValue length, +void RTDEF(PointerNullifyCharacter)(Descriptor &pointer, SubscriptValue length, int kind, int rank, int corank) { INTERNAL_CHECK(corank == 0); pointer.Establish( kind, length, nullptr, rank, nullptr, CFI_attribute_pointer); } -void RTNAME(PointerNullifyDerived)(Descriptor &pointer, +void RTDEF(PointerNullifyDerived)(Descriptor &pointer, const typeInfo::DerivedType &derivedType, int rank, int corank) { INTERNAL_CHECK(corank == 0); pointer.Establish(derivedType, nullptr, rank, nullptr, CFI_attribute_pointer); } -void RTNAME(PointerSetBounds)(Descriptor &pointer, int zeroBasedDim, +void RTDEF(PointerSetBounds)(Descriptor &pointer, int zeroBasedDim, SubscriptValue lower, SubscriptValue upper) { INTERNAL_CHECK(zeroBasedDim >= 0 && zeroBasedDim < pointer.rank()); pointer.GetDimension(zeroBasedDim).SetBounds(lower, upper); @@ -47,28 +48,28 @@ void RTNAME(PointerSetBounds)(Descriptor &pointer, int zeroBasedDim, // TODO: PointerSetCoBounds -void RTNAME(PointerSetDerivedLength)( +void RTDEF(PointerSetDerivedLength)( Descriptor &pointer, int which, SubscriptValue x) { DescriptorAddendum *addendum{pointer.Addendum()}; INTERNAL_CHECK(addendum != nullptr); addendum->SetLenParameterValue(which, x); } -void RTNAME(PointerApplyMold)( +void RTDEF(PointerApplyMold)( Descriptor &pointer, const Descriptor &mold, int rank) { pointer.ApplyMold(mold, rank); } -void RTNAME(PointerAssociateScalar)(Descriptor &pointer, void *target) { +void RTDEF(PointerAssociateScalar)(Descriptor &pointer, void *target) { pointer.set_base_addr(target); } -void RTNAME(PointerAssociate)(Descriptor &pointer, const Descriptor &target) { +void RTDEF(PointerAssociate)(Descriptor &pointer, const Descriptor &target) { pointer = target; pointer.raw().attribute = CFI_attribute_pointer; } -void RTNAME(PointerAssociateLowerBounds)(Descriptor &pointer, +void RTDEF(PointerAssociateLowerBounds)(Descriptor &pointer, const Descriptor &target, const Descriptor &lowerBounds) { pointer = target; pointer.raw().attribute = CFI_attribute_pointer; @@ -84,7 +85,7 @@ void RTNAME(PointerAssociateLowerBounds)(Descriptor &pointer, } } -void RTNAME(PointerAssociateRemapping)(Descriptor &pointer, +void RTDEF(PointerAssociateRemapping)(Descriptor &pointer, const Descriptor &target, const Descriptor &bounds, const char *sourceFile, int sourceLine) { pointer = target; @@ -122,7 +123,7 @@ void RTNAME(PointerAssociateRemapping)(Descriptor &pointer, } } -int RTNAME(PointerAllocate)(Descriptor &pointer, bool hasStat, +int RTDEF(PointerAllocate)(Descriptor &pointer, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!pointer.IsPointer()) { @@ -141,7 +142,7 @@ int RTNAME(PointerAllocate)(Descriptor &pointer, bool hasStat, return stat; } -int RTNAME(PointerAllocateSource)(Descriptor &pointer, const Descriptor &source, +int RTDEF(PointerAllocateSource)(Descriptor &pointer, const Descriptor &source, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { int stat{RTNAME(PointerAllocate)( @@ -153,7 +154,7 @@ int RTNAME(PointerAllocateSource)(Descriptor &pointer, const Descriptor &source, return stat; } -int RTNAME(PointerDeallocate)(Descriptor &pointer, bool hasStat, +int RTDEF(PointerDeallocate)(Descriptor &pointer, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!pointer.IsPointer()) { @@ -167,7 +168,7 @@ int RTNAME(PointerDeallocate)(Descriptor &pointer, bool hasStat, errMsg, hasStat); } -int RTNAME(PointerDeallocatePolymorphic)(Descriptor &pointer, +int RTDEF(PointerDeallocatePolymorphic)(Descriptor &pointer, const typeInfo::DerivedType *derivedType, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { int stat{RTNAME(PointerDeallocate)( @@ -187,11 +188,11 @@ int RTNAME(PointerDeallocatePolymorphic)(Descriptor &pointer, return stat; } -bool RTNAME(PointerIsAssociated)(const Descriptor &pointer) { +bool RTDEF(PointerIsAssociated)(const Descriptor &pointer) { return pointer.raw().base_addr != nullptr; } -bool RTNAME(PointerIsAssociatedWith)( +bool RTDEF(PointerIsAssociatedWith)( const Descriptor &pointer, const Descriptor *target) { if (!target) { return pointer.raw().base_addr != nullptr; @@ -220,5 +221,6 @@ bool RTNAME(PointerIsAssociatedWith)( // TODO: PointerCheckLengthParameter +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/product.cpp b/flang/runtime/product.cpp index 683cb61fe9951a60d9d10d10d1e6b96473d2fca0..a516bc51a959b771d3345a731f8771d5038ca728 100644 --- a/flang/runtime/product.cpp +++ b/flang/runtime/product.cpp @@ -18,13 +18,15 @@ namespace Fortran::runtime { template class NonComplexProductAccumulator { public: - explicit NonComplexProductAccumulator(const Descriptor &array) + explicit RT_API_ATTRS NonComplexProductAccumulator(const Descriptor &array) : array_{array} {} - void Reinitialize() { product_ = 1; } - template void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { + RT_API_ATTRS void Reinitialize() { product_ = 1; } + template + RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { *p = static_cast(product_); } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { product_ *= *array_.Element(at); return product_ != 0; } @@ -34,16 +36,24 @@ private: INTERMEDIATE product_{1}; }; +// Suppress the warnings about calling __host__-only std::complex operators, +// defined in C++ STD header files, from __device__ code. +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + template class ComplexProductAccumulator { public: - explicit ComplexProductAccumulator(const Descriptor &array) : array_{array} {} - void Reinitialize() { product_ = std::complex{1, 0}; } - template void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { + explicit RT_API_ATTRS ComplexProductAccumulator(const Descriptor &array) + : array_{array} {} + RT_API_ATTRS void Reinitialize() { product_ = std::complex{1, 0}; } + template + RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const { using ResultPart = typename A::value_type; *p = {static_cast(product_.real()), static_cast(product_.imag())}; } - template bool AccumulateAt(const SubscriptValue at[]) { + template + RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { product_ *= *array_.Element(at); return true; } @@ -53,37 +63,37 @@ private: std::complex product_{1, 0}; }; +RT_DIAG_POP + extern "C" { -CppTypeFor RTNAME(ProductInteger1)( - const Descriptor &x, const char *source, int line, int dim, - const Descriptor *mask) { +RT_EXT_API_GROUP_BEGIN + +CppTypeFor RTDEF(ProductInteger1)(const Descriptor &x, + const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } -CppTypeFor RTNAME(ProductInteger2)( - const Descriptor &x, const char *source, int line, int dim, - const Descriptor *mask) { +CppTypeFor RTDEF(ProductInteger2)(const Descriptor &x, + const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } -CppTypeFor RTNAME(ProductInteger4)( - const Descriptor &x, const char *source, int line, int dim, - const Descriptor *mask) { +CppTypeFor RTDEF(ProductInteger4)(const Descriptor &x, + const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } -CppTypeFor RTNAME(ProductInteger8)( - const Descriptor &x, const char *source, int line, int dim, - const Descriptor *mask) { +CppTypeFor RTDEF(ProductInteger8)(const Descriptor &x, + const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } #ifdef __SIZEOF_INT128__ -CppTypeFor RTNAME(ProductInteger16)( +CppTypeFor RTDEF(ProductInteger16)( const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, @@ -94,27 +104,27 @@ CppTypeFor RTNAME(ProductInteger16)( #endif // TODO: real/complex(2 & 3) -CppTypeFor RTNAME(ProductReal4)(const Descriptor &x, +CppTypeFor RTDEF(ProductReal4)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } -CppTypeFor RTNAME(ProductReal8)(const Descriptor &x, +CppTypeFor RTDEF(ProductReal8)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } #if LDBL_MANT_DIG == 64 -CppTypeFor RTNAME(ProductReal10)(const Descriptor &x, +CppTypeFor RTDEF(ProductReal10)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, "PRODUCT"); } #elif LDBL_MANT_DIG == 113 -CppTypeFor RTNAME(ProductReal16)(const Descriptor &x, +CppTypeFor RTDEF(ProductReal16)(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { return GetTotalReduction(x, source, line, dim, mask, NonComplexProductAccumulator>{x}, @@ -122,14 +132,14 @@ CppTypeFor RTNAME(ProductReal16)(const Descriptor &x, } #endif -void RTNAME(CppProductComplex4)(CppTypeFor &result, +void RTDEF(CppProductComplex4)(CppTypeFor &result, const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { result = GetTotalReduction(x, source, line, dim, mask, ComplexProductAccumulator>{x}, "PRODUCT"); } -void RTNAME(CppProductComplex8)(CppTypeFor &result, +void RTDEF(CppProductComplex8)(CppTypeFor &result, const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { result = GetTotalReduction(x, source, line, dim, @@ -137,7 +147,7 @@ void RTNAME(CppProductComplex8)(CppTypeFor &result, "PRODUCT"); } #if LDBL_MANT_DIG == 64 -void RTNAME(CppProductComplex10)(CppTypeFor &result, +void RTDEF(CppProductComplex10)(CppTypeFor &result, const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { result = GetTotalReduction(x, source, line, dim, @@ -145,7 +155,7 @@ void RTNAME(CppProductComplex10)(CppTypeFor &result, "PRODUCT"); } #elif LDBL_MANT_DIG == 113 -void RTNAME(CppProductComplex16)(CppTypeFor &result, +void RTDEF(CppProductComplex16)(CppTypeFor &result, const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask) { result = GetTotalReduction(x, source, line, dim, @@ -154,11 +164,13 @@ void RTNAME(CppProductComplex16)(CppTypeFor &result, } #endif -void RTNAME(ProductDim)(Descriptor &result, const Descriptor &x, int dim, +void RTDEF(ProductDim)(Descriptor &result, const Descriptor &x, int dim, const char *source, int line, const Descriptor *mask) { TypedPartialNumericReduction( result, x, dim, source, line, mask, "PRODUCT"); } + +RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime diff --git a/flang/runtime/ragged.cpp b/flang/runtime/ragged.cpp index 855aa02e7f5963e7f6c4824f1cd3afc069b1ce2f..a4d9e541ba5311906766c55faa9ca945271976dc 100644 --- a/flang/runtime/ragged.cpp +++ b/flang/runtime/ragged.cpp @@ -7,20 +7,22 @@ //===----------------------------------------------------------------------===// #include "flang/Runtime/ragged.h" +#include "tools.h" #include namespace Fortran::runtime { -inline bool isIndirection(const RaggedArrayHeader *const header) { +inline RT_API_ATTRS bool isIndirection(const RaggedArrayHeader *const header) { return header->flags & 1; } -inline std::size_t rank(const RaggedArrayHeader *const header) { +inline RT_API_ATTRS std::size_t rank(const RaggedArrayHeader *const header) { return header->flags >> 1; } -RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader, - std::int64_t rank, std::int64_t elementSize, std::int64_t *extentVector) { +RT_API_ATTRS RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, + bool isHeader, std::int64_t rank, std::int64_t elementSize, + std::int64_t *extentVector) { if (header && rank) { std::int64_t size{1}; for (std::int64_t counter{0}; counter < rank; ++counter) { @@ -32,10 +34,13 @@ RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader, header->flags = (rank << 1) | isHeader; header->extentPointer = extentVector; if (isHeader) { - header->bufferPointer = std::calloc(sizeof(RaggedArrayHeader), size); - } else { - header->bufferPointer = - static_cast(std::calloc(elementSize, size)); + elementSize = sizeof(RaggedArrayHeader); + } + Terminator terminator{__FILE__, __LINE__}; + std::size_t bytes{static_cast(elementSize * size)}; + header->bufferPointer = AllocateMemoryOrCrash(terminator, bytes); + if (header->bufferPointer) { + std::memset(header->bufferPointer, 0, bytes); } return header; } else { @@ -44,7 +49,7 @@ RaggedArrayHeader *RaggedArrayAllocate(RaggedArrayHeader *header, bool isHeader, } // Deallocate a ragged array from the heap. -void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) { +RT_API_ATTRS void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) { if (raggedArrayHeader) { if (std::size_t end{rank(raggedArrayHeader)}) { if (isIndirection(raggedArrayHeader)) { @@ -66,14 +71,14 @@ void RaggedArrayDeallocate(RaggedArrayHeader *raggedArrayHeader) { } extern "C" { -void *RTNAME(RaggedArrayAllocate)(void *header, bool isHeader, - std::int64_t rank, std::int64_t elementSize, std::int64_t *extentVector) { +void *RTDEF(RaggedArrayAllocate)(void *header, bool isHeader, std::int64_t rank, + std::int64_t elementSize, std::int64_t *extentVector) { auto *result = RaggedArrayAllocate(static_cast(header), isHeader, rank, elementSize, extentVector); return static_cast(result); } -void RTNAME(RaggedArrayDeallocate)(void *raggedArrayHeader) { +void RTDEF(RaggedArrayDeallocate)(void *raggedArrayHeader) { RaggedArrayDeallocate(static_cast(raggedArrayHeader)); } } // extern "C" diff --git a/flang/runtime/reduction-templates.h b/flang/runtime/reduction-templates.h index 2aaf5c102a9ca9ef9c410ed387759b2d4012a44f..cf1ee8a967750dfc357e251cb61e2c7f35f01b72 100644 --- a/flang/runtime/reduction-templates.h +++ b/flang/runtime/reduction-templates.h @@ -40,7 +40,7 @@ namespace Fortran::runtime { // cases of FINDLOC, MAXLOC, & MINLOC). These are the cases without DIM= or // cases where the argument has rank 1 and DIM=, if present, must be 1. template -inline void DoTotalReduction(const Descriptor &x, int dim, +inline RT_API_ATTRS void DoTotalReduction(const Descriptor &x, int dim, const Descriptor *mask, ACCUMULATOR &accumulator, const char *intrinsic, Terminator &terminator) { if (dim < 0 || dim > 1) { @@ -76,7 +76,7 @@ inline void DoTotalReduction(const Descriptor &x, int dim, } template -inline CppTypeFor GetTotalReduction(const Descriptor &x, +inline RT_API_ATTRS CppTypeFor GetTotalReduction(const Descriptor &x, const char *source, int line, int dim, const Descriptor *mask, ACCUMULATOR &&accumulator, const char *intrinsic) { Terminator terminator{source, line}; @@ -98,7 +98,7 @@ inline CppTypeFor GetTotalReduction(const Descriptor &x, // lower bounds other than one. This utility subroutine creates an // array of subscripts [j,_,k] for result subscripts [j,k] so that the // elements of array(j,:,k) can be reduced. -inline void GetExpandedSubscripts(SubscriptValue at[], +inline RT_API_ATTRS void GetExpandedSubscripts(SubscriptValue at[], const Descriptor &descriptor, int zeroBasedDim, const SubscriptValue from[]) { descriptor.GetLowerBounds(at); @@ -113,8 +113,9 @@ inline void GetExpandedSubscripts(SubscriptValue at[], } template -inline void ReduceDimToScalar(const Descriptor &x, int zeroBasedDim, - SubscriptValue subscripts[], TYPE *result, ACCUMULATOR &accumulator) { +inline RT_API_ATTRS void ReduceDimToScalar(const Descriptor &x, + int zeroBasedDim, SubscriptValue subscripts[], TYPE *result, + ACCUMULATOR &accumulator) { SubscriptValue xAt[maxRank]; GetExpandedSubscripts(xAt, x, zeroBasedDim, subscripts); const auto &dim{x.GetDimension(zeroBasedDim)}; @@ -133,9 +134,9 @@ inline void ReduceDimToScalar(const Descriptor &x, int zeroBasedDim, } template -inline void ReduceDimMaskToScalar(const Descriptor &x, int zeroBasedDim, - SubscriptValue subscripts[], const Descriptor &mask, TYPE *result, - ACCUMULATOR &accumulator) { +inline RT_API_ATTRS void ReduceDimMaskToScalar(const Descriptor &x, + int zeroBasedDim, SubscriptValue subscripts[], const Descriptor &mask, + TYPE *result, ACCUMULATOR &accumulator) { SubscriptValue xAt[maxRank], maskAt[maxRank]; GetExpandedSubscripts(xAt, x, zeroBasedDim, subscripts); GetExpandedSubscripts(maskAt, mask, zeroBasedDim, subscripts); @@ -162,7 +163,7 @@ inline void ReduceDimMaskToScalar(const Descriptor &x, int zeroBasedDim, // Utility: establishes & allocates the result array for a partial // reduction (i.e., one with DIM=). -static void CreatePartialReductionResult(Descriptor &result, +static RT_API_ATTRS void CreatePartialReductionResult(Descriptor &result, const Descriptor &x, std::size_t resultElementSize, int dim, Terminator &terminator, const char *intrinsic, TypeCode typeCode) { int xRank{x.rank()}; @@ -192,9 +193,10 @@ static void CreatePartialReductionResult(Descriptor &result, // Partial reductions with DIM= template -inline void PartialReduction(Descriptor &result, const Descriptor &x, - std::size_t resultElementSize, int dim, const Descriptor *mask, - Terminator &terminator, const char *intrinsic, ACCUMULATOR &accumulator) { +inline RT_API_ATTRS void PartialReduction(Descriptor &result, + const Descriptor &x, std::size_t resultElementSize, int dim, + const Descriptor *mask, Terminator &terminator, const char *intrinsic, + ACCUMULATOR &accumulator) { CreatePartialReductionResult(result, x, resultElementSize, dim, terminator, intrinsic, TypeCode{CAT, KIND}); SubscriptValue at[maxRank]; @@ -233,8 +235,8 @@ struct PartialIntegerReductionHelper { template struct Functor { static constexpr int Intermediate{ std::max(KIND, 4)}; // use at least "int" for intermediate results - void operator()(Descriptor &result, const Descriptor &x, int dim, - const Descriptor *mask, Terminator &terminator, + RT_API_ATTRS void operator()(Descriptor &result, const Descriptor &x, + int dim, const Descriptor *mask, Terminator &terminator, const char *intrinsic) const { using Accumulator = ACCUM>; @@ -248,9 +250,9 @@ struct PartialIntegerReductionHelper { }; template